2017-02-16 12 views
0

Я посмотрел на этот вопрос (Please help merging 4 MySQL queries to One), надеясь, что это поможет, но это не так. Я не могу понять, потому что мой мозг жарится.Слияние нескольких инструкций SELECT MySQL SELECT вычисляет поля

Я пытаюсь объединить четыре выражения SELECT, которые работают индивидуально, в одном.

Поля есть;

КОЛИЧЕСТВО: INT;

ORDERDATE: DATE; // Не datetime - мне не нужно время.

MySQL Version 5.6.17

данные я извлечения является;

1) Количество изделий, заказанных в этом финансовом году;

SELECT SUM(QUANTITY) AS YTD 
    FROM ORDERDETAILS 
    WHERE ORDERDATE BETWEEN "2016-07-01" AND "2017-02-16" 

Обратите внимание, что в Австралии финансовый год 1 июля до 30 июня.

2) Количество изделий, заказанных в этом месяце;

SELECT SUM(QUANTITY) AS MONTHY 
    FROM ORDERDETAILS 
    WHERE ORDERDATE BETWEEN "2017-02-01" AND "2017-02-16" 

3) Количество заказанных продуктов сегодня;

SELECT SUM(QUANTITY) AS TODAYS 
    FROM ORDERDETAILS 
    WHERE ORDERDATE = "2017-02-16" 

4) Среднее число заказанных продуктов за заказ;

SELECT AVG(QUANTITY) AS BOOGER 
    FROM ORDERDETAILS 
    WHERE ORDERDATE BETWEEN "2016-07-01" AND "2017-02-16" 

Я хочу, чтобы избежать отправок четыре отдельных заявлений на сервер. Возможно, этого не может быть сделано, но если бы я мог достичь тех же результатов в одном заявлении, я был бы счастлив.

Я смотрел на соединения, встраивание выбирает в пределах отборов, но не может окунуться в него.

Как только я получу данные, все, что я делаю, обновляет пару меток на форме (Delphi).

Любые советы, которые может обрабатывать мозг почти 55 лет, будут оценены по достоинству.

+0

Что бы желаемого результата выглядеть? И см. Http://meta.stackoverflow.com/questions/333952/why-should-i-provide-an-mcve-for-what-seems-to-me-to-be-a-very-simple-sql- query – Strawberry

+0

@Strawberry все, что я хочу, это числа. Существующие SELECT работают и производят один номер, который я показываю на экране. Думаю, слияние их должно вернуть четыре цифры. Я проверю ответ и посмотрю, работает ли он. Спасибо за ваш комментарий. –

ответ

0

Используйте SUM(IF()) рисунок и переместить состояние внутри IF.

SELECT 
    SUM(IF(ORDERDATE BETWEEN "2016-07-01" AND "2017-02-16", QUANTITY, 0)) AS YTD, 
    SUM(IF(ORDERDATE BETWEEN "2017-02-01" AND "2017-02-16", QUANTITY, 0)) AS MONTHY, 
    SUM(IF(ORDERDATE = "2017-02-16", QUANTITY, 0)) AS TODAYS, 
    SUM(IF(ORDERDATE BETWEEN "2016-07-01" AND "2017-02-16", QUANTITY, 0))/COUNT(IF(ORDERDATE BETWEEN "2016-07-01" AND "2017-02-16", 1, NULL)) AS BOOGER 
FROM ORDERDETAILS 
WHERE ORDERDATE BETWEEN "2016-07-01" AND "2017-02-16"; 

Рассмотрите возможность использования CURDATE() для сегодняшней даты.

Также может быть добавлено предложение WHERE, так что все строки таблицы не сканируются, например.WHERE ORDERDATE BETWEEN "2016-07-01" AND "2017-02-16" после FROM ORDERDETAILS

+0

Спасибо, что сработало отлично. Но я смущен вашим окончательным комментарием о добавлении WHERE после ORDERDETAILS. Я уже это делаю, не так ли? –

+0

В моем ответе я переместил условия для 'SUM' внутри' SUM (IF()) 'и запрос работает нормально. Но поскольку в запросе нет предложения WHERE, он будет сканировать все строки таблицы. Если вы добавите предложение WHERE, которое охватывает все диапазоны дат, запрос будет работать как можно быстрее, а также быстрее. Редактирование моего ответа, чтобы отразить его. – Sangharsh

+0

Хорошая работа. Я действительно добавил ГДЕ, когда я его протестировал, и это было упомянуто в моем вопросе, поэтому я думал, что вы имеете в виду что-то еще. Спасибо за вашу помощь. :) –

1

Вы просто должны использовать другой псевдоним на различные вызовы к столу и положили все это в одном ЗЕЬЕСТЕ следующим образом:

SELECT SUM(od1.QUANTITY) AS YTD, 
     SUM(od2.QUANTITY) AS MONTHLY, 
     SUM(od3.QUANTITY) AS TODAYS, 
     AVG(od4.QUANTITY) AS BOOGER 
FROM ORDERDETAILS od1, 
    ORDERDETAILS od2, 
    ORDERDETAILS od3, 
    ORDERDETAILS od4 
WHERE od1.ORDERDATE BETWEEN CAST('2016-07-01' AS DATE) AND CAST('2017-02-16' AS DATE) 
    AND od2.ORDERDATE BETWEEN CAST('2017-02-01' AS DATE) AND CAST('2017-02-16' AS DATE) 
    AND od3.ORDERDATE = CAST('2017-02-16' AS DATE) 
    AND od4.ORDERDATE BETWEEN CAST('2016-07-01' AS DATE) AND CAST('2017-02-16' AS DATE) 
+0

спасибо за ваш ответ. Я только что протестировал его на сервере напрямую, и он все еще работает через 3 минуты. Я вижу, где вы собираетесь с ним, но он все еще выполняет запрос. Всего около 3000 записей. :) –

+0

Это потому, что вы не можете использовать BETWEEN так. Вам нужно добавить CAST ('2016-07-01' AS DATE) –

+0

Спасибо, что нашли время, чтобы ответить, но я уже принял еще один ответ. Хотел бы вы упомянуть CAST раньше, потому что, если бы это сработало, я бы принял это. :) –

2

Вы можете сделать это, используя случай, когда условие:

select 
     sum(case when ORDERDATE BETWEEN '2016-07-01' AND '2017-02-16' then QUANTITY end) as YTD, 
     sum(case when ORDERDATE BETWEEN '2017-02-01' AND '2017-02-16' then QUANTITY end) as MONTHY, 
     sum(case when ORDERDATE = '2017-02-16' then QUANTITY end) as TODAYS, 
     AVG(case when ORDERDATE BETWEEN '2016-07-01' AND '2017-02-16' then QUANTITY end) as BOOGER 
     FROM ORDERDETAILS 
+0

Спасибо, что тоже сработало. Казалось бы, есть несколько способов достижения одного и того же. Я уже принял ответ, хотя, извините. :) –