Как выбрать SQL данных в сегментах, если данные не существуют для одного сегмента? - PullRequest
1 голос
/ 31 марта 2020

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

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

SELECT
WEEKDAY(transaction_date) AS day_of_week,
SUM(sales) AS total_sales
FROM table1
GROUP BY day_of_week

Если у меня продажи каждый день, я получу 7 строк в своем результате, представляющих общий объем продаж в дни 0-6.

Если у меня нет продаж во 2-й день, я не получаю результатов за 2-й день.

Какой самый эффективный способ установить нулевое значение для 2-го дня?

Должен ли я присоединиться к временной таблице или массиву определенных сегментов? ['0', '1', '2', '3', '4', '5', '6'] * ​​1016 *

Или лучше вставить нули за пределы MySQL после того, как я сделали запрос?

Я использую MySQL, но это общий SQL вопрос.

Ответы [ 3 ]

1 голос
/ 31 марта 2020

Для начала вам понадобится таблица календаря; что-то вроде это или это . Или создайте подмножество календаря на лету. Я не уверен в синтаксисе mySQL, но вот как он будет выглядеть в SQL Server.

DECLARE
    @FromDate DATE
  , @ToDate   DATE

-- set these variables to appropriate values
SET @FromDate = '2020-03-01';
SET @ToDate = '2020-03-31';

;WITH cteCalendar (MyDate) AS
(
    SELECT CONVERT(DATE, @FromDate) AS MyDate
    UNION ALL
    SELECT DATEADD(DAY, 1, MyDate)
    FROM   cteCalendar
    WHERE  DATEADD(DAY, 1, MyDate) <= @ToDate
)
SELECT WEEKDAY(cte.MyDate) AS day_of_week,
SUM(sales) AS total_sales
FROM cteCalendar cte
LEFT JOIN table1 t1 ON cte.MyDate = t1.transaction_date
GROUP BY day_of_week
1 голос
/ 31 марта 2020

В MySQL вы можете просто использовать производную таблицу чисел от 1 до 7, left join с таблицей, а затем агрегировать:

select d.day_of_week, sum(sales) AS total_sales
from (
    select 1 day_of_week union all select 2 union all select 3 union all select 4
    union all select 5 union all select 6 union all select 7
) d
left join table1 t1 on weekday(t1.transaction_date) = d.day_of_week
group by day_of_week

В самых последних версиях синтаксис values(row...), который сокращает запрос:

select d.day_of_week, sum(sales) AS total_sales
from (values row(1), row(2), row(3), row(4), row(5), row(6), row(7)) d(day_of_week)
left join table1 t1 on weekday(t1.transaction_date) = d.day_of_week
group by day_of_week
1 голос
/ 31 марта 2020

Как правило, вы хотите, чтобы ответ был 0, когда данные для этого сегмента фактически равны нулю, поэтому вам нужен максимум (ноль, 0). Функция max не будет изначально работать с NULL таким образом, однако вы можете использовать COALESCE для ее принудительной установки:

COALESCE(MAX(SUM(sales)),0)

, как предложено этим ответом

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...