这与此链接上的帖子有关:
datetime (datetime) count (int)
2012-12-27 09:22:15 5
2012-12-27 18:20:15 4
2012-12-27 23:19:15 3
2012-12-26 13:45:15 8
2012-12-26 04:56:15 7
2012-12-25 01:50:15 2
2012-12-25 12:02:15 1
我想总结每天的COUNT,但不仅仅是那些有入境的日子,还有那些没有入场的日子。
SELECT DATE(datetime) as DATE, SUM(`count`) totalCOunt
FROM tableName
GROUP BY DATE(datetime)
以上代码仅在有入境的那些日子返回我。
假设我想在2016年4月到2017年2月之间获得每天的总计数,我该怎么做?谢谢。例如:
2012-12-25 25
2012-12-26 NULL --> because there is no entry
答案 0 :(得分:0)
如下面的代码所示。您可以创建日历表。我们根据需要为我们提供准确的日历。 进入该日历表。
DROP TABLE IF EXISTS time_dimension;
CREATE TABLE time_dimension (
id INTEGER PRIMARY KEY, -- year*10000+month*100+day
db_date DATE NOT NULL,
year INTEGER NOT NULL,
month INTEGER NOT NULL, -- 1 to 12
day INTEGER NOT NULL, -- 1 to 31
quarter INTEGER NOT NULL, -- 1 to 4
week INTEGER NOT NULL, -- 1 to 52/53
day_name VARCHAR(9) NOT NULL, -- 'Monday', 'Tuesday'...
month_name VARCHAR(9) NOT NULL, -- 'January', 'February'...
holiday_flag CHAR(1) DEFAULT 'f' CHECK (holiday_flag in ('t', 'f')),
weekend_flag CHAR(1) DEFAULT 'f' CHECK (weekday_flag in ('t', 'f')),
event VARCHAR(50),
UNIQUE td_ymd_idx (year,month,day),
UNIQUE td_dbdate_idx (db_date)
) Engine=MyISAM;
DROP PROCEDURE IF EXISTS fill_date_dimension;
DELIMITER //
CREATE PROCEDURE fill_date_dimension(IN startdate DATE,IN stopdate DATE)
BEGIN
DECLARE currentdate DATE;
SET currentdate = startdate;
WHILE currentdate < stopdate DO
INSERT INTO time_dimension VALUES (
YEAR(currentdate)*10000+MONTH(currentdate)*100 + DAY(currentdate),
currentdate,
YEAR(currentdate),
MONTH(currentdate),
DAY(currentdate),
QUARTER(currentdate),
WEEKOFYEAR(currentdate),
DATE_FORMAT(currentdate,'%W'),
DATE_FORMAT(currentdate,'%M'),
'f',
CASE DAYOFWEEK(currentdate) WHEN 1 THEN 't' WHEN 7 then 't' ELSE 'f' END,
NULL);
SET currentdate = ADDDATE(currentdate,INTERVAL 1 DAY);
END WHILE;
END
//
DELIMITER ;
TRUNCATE TABLE time_dimension;
CALL fill_date_dimension('2000-01-01','2018-01-01');
创建该日历表后,您可以在下面写下查询,它将解决您的问题。
SELECT COUNT(datetime) ,DB_DATE FROM time_dimension TD
LEFT JOIN TABLENAME TN ON DATE(TN.datetime)=TD.db_date
WHERE TD.DB_DATE BETWEEN '2017-05-01' AND '2017-05-30'
GROUP BY DATE(DB_DATE);
希望这会有所帮助。
答案 1 :(得分:0)
请尝试以下方法......
DROP PROCEDURE IF EXISTS SumCountAllDays;
DELIMITER //
CREATE PROCEDURE SumCountAllDays( startDate DATE,
endDate DATE )
BEGIN
DECLARE daysCount INT;
DECLARE daysIndex INT DEFAULT 0;
SELECT DATEDIFF( endDate,
startDate )
INTO daysCount;
SET @selectStatementString := CONCAT( "SELECT allDays.intervalDate AS `Date`,",
" COALESCE( SUM( `count` ), 0 ) AS totalCount ",
"FROM ( SELECT '",
startDate,
"' AS intervalDate" );
daysLister : LOOP
SET daysIndex = daysIndex + 1;
IF daysIndex <= daysCount THEN
SET @selectStatementString := CONCAT( @selectStatementString,
" UNION SELECT '",
DATE_ADD( startDate,
INTERVAL daysIndex DAY ),
"'" );
ITERATE daysLister;
END IF;
LEAVE daysLister;
END LOOP daysLister;
SET @selectStatementString := CONCAT( @selectStatementString,
" ) AS allDays ",
"LEFT JOIN tableName ON allDays.intervalDate = DATE( `datetime` ) ",
"GROUP BY allDays.intervalDate;" );
PREPARE selectStatement FROM @selectStatementString;
EXECUTE selectStatement;
DEALLOCATE PREPARE selectStatement;
END //
DELIMITER ;
当您摆弄代码并希望删除旧版本时,第一行非常方便。
其余代码会创建一个过程,在调用并传递相关时段的开始日期和结束日期时,使用DATEDIFF()
来计算startDate
和{之间的天数{1}},将值存储在endDate
。
然后,该过程将daysCount
初始化为最终语句的第一部分。第一部分以一系列@selectStatementString
语句中的第一部分结束,这些语句用于选择SELECT
和startDate
之间的每个日期。 endDate
初始值的SELECT
是由所有这些日期的联合形成的字段的名称startDate
。
循环然后为每个日期附加intervalDate
,这些日期是根据循环索引SELECT
计算的。
daysIndex
运算符用于在每个生成日期执行垂直连接。
UNION
完成后,语句的其余部分将附加到语句到目前为止。如果LOOP
和startDate
为endDate
和2012-02-13
,那么我们现在会有以下声明......
2012-02-15
我针对使用以下脚本创建的测试数据库测试了我的语句...
SELECT allDays.intervalDate AS `Date`,
COUNT( `count` ) AS totalCount
FROM ( SELECT '2012-02-13' AS intervalDate
UNION
SELECT '2012-02-14'
UNION
SELECT '2012-02-15' ) AS allDays
LEFT JOIN tableName ON allDays.intervalDate = DATE( `datetime` )
GROUP BY allDays.intervalDate;
我使用以下声明调用了该程序......
CREATE TABLE tableName
(
`datetime` DATETIME,
`count` INT
);
INSERT INTO tableName ( `datetime`,
`count` )
VALUES ( '2012-12-27 09:22:15', 5 ),
( '2012-12-27 18:20:15', 4 ),
( '2012-12-27 23:19:15', 3 ),
( '2012-12-26 13:45:15', 8 ),
( '2012-12-26 04:56:15', 7 ),
( '2012-12-25 01:50:15', 2 ),
( '2012-12-25 12:02:15', 1 );
如果您有任何问题或意见,请随时发表评论。