Наш набор данных в основном объединяет набор дат (недели от текущей недели до прошлого) с набором разделов, основанных на том, начинались ли эти разделы в или до и заканчивались в или после этой недели. Хотя изначально этот запрос дал нам ожидаемые результаты, на этой неделе он начал давать нам неправильные результаты. После нескольких попыток мы обнаружили, что если мы изменили запрос на LEFT JOIN
, а затем отфильтровали запрос с помощью предложения WHERE
, он снова дал бы нам правильные результаты.
В чем разница? Почему один работает, а другой нет? ( Бонусные баллы: почему исходный запрос работал в течение нескольких недель, прежде чем внезапно возникла эта ошибка?) Выполнение того же внутреннего соединения в Redshift дает правильные результаты, так что это нюанс снежинки, который мы не понимаем .
Исходный запрос:
WITH week_list AS
(
SELECT DATEADD(week, -4, DATE_TRUNC(week, CURRENT_DATE())) AS week_value
UNION ALL
SELECT DATEADD(week, 1, week_value)
FROM week_list
WHERE DATEADD(week, 1, week_value) < CURRENT_DATE()
),
active_sections_per_week AS
(
SELECT
wl.week_value, s.id section_id
FROM week_list wl
JOIN schema.sections s ON wl.week_value >= DATE_TRUNC(week, s.starts_at)
AND wl.week_value <= DATE_TRUNC(week, s.ends_at)
)
SELECT
aspw.week_value,
COUNT(DISTINCT aspw.section_id) count_sections
FROM
active_sections_per_week aspw
GROUP BY 1
ORDER BY 1 DESC
Результаты: Одна строка, датированная 2019-12-30 (4 недели go) , Нет данных за последние три недели.
Примечание. Если вы отрегулируете DATEADD
в первом CTE, то, какова бы ни была возвращенная первая дата, всегда будет успешно выполнено присоединение. Такое поведение началось только в течение последней недели - ранее этот запрос предоставлял ожидаемое количество строк (другими словами, количество недель, указанное в этом первом DATEADD
).
«Исправлено» запрос:
WITH week_list AS
(
SELECT DATEADD(week, -4, DATE_TRUNC(week, CURRENT_DATE())) AS week_value
UNION ALL
SELECT DATEADD(week, 1, week_value)
FROM week_list
WHERE DATEADD(week, 1, week_value) < CURRENT_DATE()
),
active_sections_per_week AS
(
SELECT wl.week_value, s.id section_id
FROM week_list wl
LEFT JOIN schema.sections s ON wl.week_value >= DATE_TRUNC(week, s.starts_at)
AND wl.week_value <= DATE_TRUNC(week, s.ends_at)
WHERE s.id IS NOT NULL
)
SELECT aspw.week_value, COUNT(DISTINCT aspw.section_id) count_sections
FROM active_sections_per_week aspw
GROUP BY 1
ORDER BY 1 DESC
Результаты: возвращает четыре строки, недели от 2019-12-30 до 2020-01-20, с соответствующим количеством секций.