我的数据库中有很多记录,为了数据分析,我需要显示每天的记录数,包括我没有任何记录的日子,所以结果是0
.
例如我有这些记录(SQL Fiddle):
CREATE TABLE Tabs
(`timestamp` varchar(10), `id` int)
;
INSERT INTO Tabs
(`timestamp`, `id`)
VALUES
('2015-01-01', 1),
('2015-01-01', 2),
('2015-01-02', 3),
('2015-01-02', 4),
('2015-01-02', 5),
('2015-01-04', 6),
('2015-01-05', 7),
('2015-01-05', 8)
;
Run Code Online (Sandbox Code Playgroud)
当我使用此查询时:
SELECT `timestamp`, COUNT(*)
FROM Tabs
GROUP BY `timestamp`
Run Code Online (Sandbox Code Playgroud)
我得到了结果:
timestamp COUNT(*)
2015-01-01 2
2015-01-02 3
2015-01-04 1
2015-01-05 2
Run Code Online (Sandbox Code Playgroud)
但我也需要2015-01-03
with 0
,所以对我来说正确的输出是:
timestamp COUNT(*)
2015-01-01 2
2015-01-02 3
2015-01-02 0
2015-01-04 1
2015-01-05 2
Run Code Online (Sandbox Code Playgroud)
请问我怎样才能意识到呢?
我想你知道的date_start
和date_end
,尽管它可以扩展你不会超过1000个工作日内上。
此示例适用于以下值:
SET @date_start := CAST('20150101' as date);
SET @date_end := CAST('20150108' as date);
Run Code Online (Sandbox Code Playgroud)
以下查询在@date_start
(2015-01-01) 和@date_end
(2015-01-08)之间每天返回。这类似于日历。然后,完整的天数列表可以是LEFT JOIN
表中可用天数的列表。
SELECT ... UNION ALL ...
SELECT @date := date_add(@date, INTERVAL 1 DAY) as date
FROM (
SELECT 0 as n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4
UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
)d10, (
SELECT 0 as n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4
UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
)d100, (
SELECT 0 as n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4
UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
) d1000
, (SELECT @date := date_add(@date_start, INTERVAL -1 DAY)) v
WHERE @date < @date_end
;
Run Code Online (Sandbox Code Playgroud)
date
2015-01-01
2015-01-02
2015-01-03
2015-01-04
2015-01-05
2015-01-06
2015-01-07
2015-01-08
Run Code Online (Sandbox Code Playgroud)
SELECT ... UNION ALL ...
返回 0 到 9 的 10 行SELECT
被使用了CROSS JOIN
3 次并从第 0 天到第 999 天返回 1000 行(10*10*10)SELECT ... UNION ALL ...
,依此类推,如果删除第三个连接,则可以工作100天创建一个数字从 0 到 9 的视图并 CROSS JOIN 它 3 次或创建 1 个从 0 到 999 的单个视图可能更容易:
CREATE VIEW viewDec As
SELECT 0 as n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4
UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
;
SELECT @date := date_add(@date, INTERVAL 1 DAY) as date
FROM viewDec d10, viewDec d100, viewDec d1000
, (SELECT @date := date_add(@date_start, INTERVAL -1 DAY)) v
WHERE @date < @date_end
;
Run Code Online (Sandbox Code Playgroud)
viewDec d10000
...工作 10.000 天也可以将SELECT
或替换为VIEW
具有足够行(在本例中为 1000)的现有表:
SELECT @date := date_add(@date, INTERVAL 1 DAY) as date
FROM (SELECT 1 as n FROM table_with_over_1000_rows LIMIT 1000) t
, (SELECT @date := date_add(@date_start, INTERVAL -1 DAY)) v
WHERE @date < @date_end
;
Run Code Online (Sandbox Code Playgroud)
SELECT `date`, count(t.`id`)
FROM (
SELECT @date := date_add(@date, INTERVAL 1 DAY) as date
FROM viewDec d10, viewDec d100, viewDec d1000
, (SELECT @date := date_add(@date_start, INTERVAL -1 DAY)) v
WHERE @date < @date_end
) d
LEFT JOIN (
SELECT `id`, `timestamp`
FROM Tabs
/* WHERE sensor = 10 */
) t
ON d.`date` = t.`timestamp`
GROUP BY d.`date`
;
Run Code Online (Sandbox Code Playgroud)
在此SQL Fiddle timestamp
中,已替换为类型日期列。
date count(t.`id`)
2015-01-01 2
2015-01-02 3
2015-01-03 0
2015-01-04 1
2015-01-05 2
2015-01-06 0
2015-01-07 0
2015-01-08 0
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
108 次 |
最近记录: |