我是SQL的新手,如果日期范围之间缺少任何日期,我想在日期范围之间的查询结果中添加一行。
这是我的查询
SELECT CHECKINOUT.USERID, USERINFO.USERID,
CAST(CHECKTIME AS DATE) DATE,
MAX(CAST(CHECKTIME AS TIME)) as MAX_TIME,
MIN(CAST(CHECKTIME AS TIME)) as MIN_TIME
FROM CHECKINOUT
LEFT JOIN USERINFO
ON CHECKINOUT.USERID = USERINFO.USERID
WHERE CHECKTIME BETWEEN '2020-02-01' AND '2020-02-10'
GROUP BY CHECKINOUT.USERID,CAST(CHECKTIME AS DATE), USERINFO.USERID, USERINFO.NAME
ORDER by CAST(CHECKTIME AS DATE), USERINFO.NAME ASC
此查询的输出
USERID USERID DATE MAX_TIME MIN_TIME
59 59 2/3/2020 4:11:48 PM 8:47:02 AM
59 59 2/4/2020 6:22:38 PM 8:45:50 AM
59 59 2/6/2020 2:33:43 PM 1:57:55 PM
59 59 2/7/2020 4:29:40 PM 8:39:38 AM
60 60 2/3/2020 4:11:48 PM 8:47:02 AM
60 60 2/4/2020 6:22:38 PM 8:45:50 AM
60 60 2/6/2020 2:33:43 PM 1:57:55 PM
60 60 2/7/2020 4:29:40 PM 8:39:38 AM
61 61 2/3/2020 4:11:48 PM 8:47:02 AM
61 61 2/4/2020 6:22:38 PM 8:45:50 AM
61 61 2/6/2020 2:33:43 PM 1:57:55 PM
61 61 2/7/2020 4:29:40 PM 8:39:38 AM
和我的预期输出
USERID USERID DATE MAX_TIME MIN_TIME
59 59 2/1/2020 NULL NULL
59 59 2/2/2020 NULL NULL
59 59 2/3/2020 4:11:48 PM 8:47:02 AM
59 59 2/4/2020 6:22:38 PM 8:45:50 AM
59 59 2/6/2020 2:33:43 PM 1:57:55 PM
59 59 2/7/2020 4:29:40 PM 8:39:38 AM
59 59 2/8/2020 NULL NULL
59 59 2/9/2020 NULL NULL
59 59 2/10/2020 NULL NULL
60 60 2/1/2020 NULL NULL
60 60 2/2/2020 NULL NULL
60 60 2/3/2020 4:11:48 PM 8:47:02 AM
60 60 2/4/2020 6:22:38 PM 8:45:50 AM
60 60 2/6/2020 2:33:43 PM 1:57:55 PM
60 60 2/7/2020 4:29:40 PM 8:39:38 AM
60 60 2/8/2020 NULL NULL
60 60 2/9/2020 NULL NULL
60 60 2/10/2020 NULL NULL
61 61 2/1/2020 NULL NULL
61 61 2/2/2020 NULL NULL
61 61 2/3/2020 4:11:48 PM 8:47:02 AM
61 61 2/4/2020 6:22:38 PM 8:45:50 AM
61 61 2/6/2020 2:33:43 PM 1:57:55 PM
61 61 2/7/2020 4:29:40 PM 8:39:38 AM
61 61 2/8/2020 NULL NULL
61 61 2/9/2020 NULL NULL
61 61 2/10/2020 NULL NULL
谁能帮我吗?
Mysql本身不能返回不存在的数据的行,您必须自己解决它,使其创建那些空行。
我有一个类似的question,您可以参考this answer以实现您想要的。
您基本上使用一个表,该表具有足够的行来提供所需的空行数(上面我用information_schema.columns
链接的答案),并与一个变量结合以生成具有递增值(m,...,n
)的行,那么您可以使用这些行和这些值来生成所需的丢失数据,例如用例的日期,最后将这些默认值行与实际数据行连接起来。
您需要生成日期列表。您可以通过多种方式执行此操作:
然后使用CROSS JOIN
生成所需的行。最后是LEFT JOIN
来引入您已经计算的数据。
这里是一个例子:
WITH uc AS (
SELECT c.USERID, CAST(CHECKTIME AS DATE) as DATE,
MAX(CAST(CHECKTIME AS TIME)) as MAX_TIME,
MIN(CAST(CHECKTIME AS TIME)) as MIN_TIME
FROM CHECKINOUT c LEFT JOIN
USERINFO u
ON i.USERID = u.USERID
WHERE c.CHECKTIME BETWEEN '2020-02-01' AND '2020-02-10'
GROUP BY c.USERID, CAST(CHECKTIME AS DATE), u.USERID, u.NAME
)
SELECT u.USERID, d.dte, uc.min_time, uc.max_time
FROM (SELECT DISTINCT USERID FROM uc) u CROSS JOIN
(SELECT CAST('2020-02-01' as DATE) as dte UNION ALL
SELECT CAST('2020-02-02' as DATE) as dte UNION ALL
. . .
SELECT CAST('2020-02-10' as DATE) as dte UNION ALL
) d LEFT JOIN
cu
ON cu.USERID = u.USERID AND cu.DATE = d.dte
ORDER by d.dte, NAME ASC