将缺失日期添加到每个位置 - MySQL 5.7
Adding Missing Dates To Each Location - MySQL 5.7
所以我的 SQL 输出是:
DUNF 2021-04-01 18
DUNF 2021-04-02 17
DUNF 2021-04-03 7
DUNF 2021-04-04 10
DUNF 2021-04-05 18
DUNF 2021-04-06 20
DUNF 2021-04-07 17
DUNF 2021-04-08 14
LEEDS 2021-04-01 4
LEEDS 2021-04-02 4
LEEDS 2021-04-03 5
LEEDS 2021-04-05 9
LEEDS 2021-04-06 3
LEEDS 2021-04-07 1
LEEDS 2021-04-08 3
etc.
但我需要每天都有一个条目,即使最后一个字段是一个卷(有时那天那个位置什么也没有发生)。
我已经尝试了所有方法,但我的 SQL 5.7 知识薄弱。我可以生成一个日历 table,但它不会填补每个站点的空白(您可以看到 Leeds 缺少一天,但还有其他站点也缺少日期)。
目前我使用的代码是:
SELECT location, begin_date, count(*) as volume
FROM abs_raw_data
WHERE begin_date >= (SELECT date_sub(max(begin_date), interval 7 day) from abs_raw_data)
GROUP BY location, begin_date
ORDER BY location asc, begin_date asc
我该怎么做呢?
看来你需要
SELECT locations.location,
calendar.begin_date,
COALESCE(COUNT(abs_raw_data.location), 0) as volume
FROM ( {calendar generating subquery} ) AS calendar
CROSS JOIN ( SELECT DISTINCT location
FROM abs_raw_data ) locations
CROSS JOIN ( SELECT MAX(begin_date) - INTERVAL 7 DAY AS begin_date
FROM abs_raw_data ) maxdate
LEFT JOIN abs_raw_data ON calendar.begin_date = abs_raw_data.begin_date
AND locations.location = abs_raw_data.location
AND abs_raw_data.begin_date >= maxdate.begin_date
GROUP BY locations.location, calendar.begin_date
ORDER BY locations.location ASC, calendar.begin_date ASC
日历生成子查询可能是,例如,
SELECT abs_raw_data.begin_date - INTERVAL nums.n DAY
FROM ( SELECT MAX(begin_date) begin_date
FROM abs_raw_data) abs_raw_data
CROSS JOIN ( SELECT 0 n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3
UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 ) nums
-- https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=49ef261eaf01956973d4ce99f6203a91
另一个答案建议生成日期。但是,我会创建一个名为 years as
的 table
years(year)
另一个叫月如
months(month)
另一个叫做 days as
days(month, day)
正确填写所有内容,包括 2 月 29 日。因此,如果您想以这种方式生成日期和月份,那么您将需要一个连接,例如:
select years.year, months.month, days.day
from years
join months
on 1
join days
on months.month = days.month and
((days.day <> 29) or (months.month <> 2) or (years.year % 4 > 0))
where (
years.year > 2020 and
years.year < 2025 and
) or
(
years.year = 2020 and
years.year = 2025 and
months.month < 11 and
months.month > 2 and
) or
(
years.year = 2020 and
years.year = 2025 and
months.month = 11 and
months.month = 2 and
days.day >= 2 and
days.day <= 21 and
)
确保插入任何可能使用的年份,插入一年中的所有月份和一个月中的所有日期,然后将以上内容用作子查询。
所以我的 SQL 输出是:
DUNF 2021-04-01 18
DUNF 2021-04-02 17
DUNF 2021-04-03 7
DUNF 2021-04-04 10
DUNF 2021-04-05 18
DUNF 2021-04-06 20
DUNF 2021-04-07 17
DUNF 2021-04-08 14
LEEDS 2021-04-01 4
LEEDS 2021-04-02 4
LEEDS 2021-04-03 5
LEEDS 2021-04-05 9
LEEDS 2021-04-06 3
LEEDS 2021-04-07 1
LEEDS 2021-04-08 3
etc.
但我需要每天都有一个条目,即使最后一个字段是一个卷(有时那天那个位置什么也没有发生)。
我已经尝试了所有方法,但我的 SQL 5.7 知识薄弱。我可以生成一个日历 table,但它不会填补每个站点的空白(您可以看到 Leeds 缺少一天,但还有其他站点也缺少日期)。
目前我使用的代码是:
SELECT location, begin_date, count(*) as volume
FROM abs_raw_data
WHERE begin_date >= (SELECT date_sub(max(begin_date), interval 7 day) from abs_raw_data)
GROUP BY location, begin_date
ORDER BY location asc, begin_date asc
我该怎么做呢?
看来你需要
SELECT locations.location,
calendar.begin_date,
COALESCE(COUNT(abs_raw_data.location), 0) as volume
FROM ( {calendar generating subquery} ) AS calendar
CROSS JOIN ( SELECT DISTINCT location
FROM abs_raw_data ) locations
CROSS JOIN ( SELECT MAX(begin_date) - INTERVAL 7 DAY AS begin_date
FROM abs_raw_data ) maxdate
LEFT JOIN abs_raw_data ON calendar.begin_date = abs_raw_data.begin_date
AND locations.location = abs_raw_data.location
AND abs_raw_data.begin_date >= maxdate.begin_date
GROUP BY locations.location, calendar.begin_date
ORDER BY locations.location ASC, calendar.begin_date ASC
日历生成子查询可能是,例如,
SELECT abs_raw_data.begin_date - INTERVAL nums.n DAY
FROM ( SELECT MAX(begin_date) begin_date
FROM abs_raw_data) abs_raw_data
CROSS JOIN ( SELECT 0 n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3
UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 ) nums
-- https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=49ef261eaf01956973d4ce99f6203a91
另一个答案建议生成日期。但是,我会创建一个名为 years as
的 tableyears(year)
另一个叫月如
months(month)
另一个叫做 days as
days(month, day)
正确填写所有内容,包括 2 月 29 日。因此,如果您想以这种方式生成日期和月份,那么您将需要一个连接,例如:
select years.year, months.month, days.day
from years
join months
on 1
join days
on months.month = days.month and
((days.day <> 29) or (months.month <> 2) or (years.year % 4 > 0))
where (
years.year > 2020 and
years.year < 2025 and
) or
(
years.year = 2020 and
years.year = 2025 and
months.month < 11 and
months.month > 2 and
) or
(
years.year = 2020 and
years.year = 2025 and
months.month = 11 and
months.month = 2 and
days.day >= 2 and
days.day <= 21 and
)
确保插入任何可能使用的年份,插入一年中的所有月份和一个月中的所有日期,然后将以上内容用作子查询。