ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

想在mysql结果中获取所有日期

2019-05-15 23:00:39  阅读:259  来源: 互联网

标签:mysql sql gaps-and-islands


我有mysql表名为user(id,name,join_on)join on是一个日期字段我想要的是每天显示已经创建了多少用途我可以使用group by但它只会给我用户获取的日期添加如果
日期

4/12/10  5 users added
4/13/10  2 users added
4/15/10  7 users added

这里的日期4/14/10不见了,我希望在一个月内列出所有日期.
我有一个解决方案,通过创建另一个表只用于添加日期,该表将在join_on上连接我的用户表并将给出总结果但我不想这样做,因为创建我需要创建和添加条目在日期表中,请建议采用不同的方法.

谢谢.

最佳答案:

有一种方法可以在纯SQL中执行此操作,但它有局限性.

首先,您需要将数字序列1,2,3 … n作为行(假设行中的选择行返回).

然后,您可以在此处保持联接并根据最小值和最大值之间的天数转换为日期.

 select @min_join_on := (select min(join_on) from user);
 select @no_rows := (select datediff(max(join_on), @min_join_on) from user)+1;

将为您提供所需的行数,然后您可以使用

 select adddate(@min_join_on, interval row day) from rows where row <= @no_rows;

将返回所需的日期序列,然后您可以将左联接返回到users表.
如果使用子查询,可以避免使用变量,为了便于阅读,我将其分解.

现在,问题是表行中的行数必须大于@no_rows.
对于10,000行,您可以使用最多27年的日期范围,100,000行可以使用日期范围长达273年(这感觉非常糟糕,但我担心如果您不想使用存储过程它必须看起来和感觉很尴尬).

因此,如果您可以使用此类固定日期范围,您甚至可以使用查询替换该表,例如

SELECT @row := @row + 1 as row FROM (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t, (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t2, (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t3, (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t4, (SELECT @row:=0) r

这将产生10,000行,从1到10,000,它不会非常低效.

所以最后它在单个查询中是可行的.

create table user(id INT NOT NULL AUTO_INCREMENT, name varchar(100), join_on date, PRIMARY KEY(id));

mysql> select * from user;
+----+-------+------------+
| id | name  | join_on    |
+----+-------+------------+
|  1 | user1 | 2010-04-02 | 
|  2 | user2 | 2010-04-04 | 
|  3 | user3 | 2010-04-08 | 
|  4 | user4 | 2010-04-08 | 
+----+-------+------------+
4 rows in set (0.00 sec)

insert into user values (null, 'user1', '2010-04-02'), (null, 'user2', '2010-04-04'), (null, 'user3', '2010-04-08'), (null, 'user4', '2010-04-08')


SELECT date, count(id)
FROM (
SELECT adddate((select min(join_on) from user), row-1) as date 
FROM ( 
SELECT @row := @row + 1 as row FROM (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t, (select 0 union all select 1 union all select 3 union all select 4 union all select 5 union all select 6 union all select 6 union all select 7 union all select 8 union all select 9) t2, (SELECT @row:=0) r ) n  
WHERE n.row <= ( select datediff(max(join_on), min(join_on)) from user) + 1
) dr LEFT JOIN user u ON dr.date = u.join_on
GROUP BY dr.date

+------------+-----------+
| date       | count(id) |
+------------+-----------+
| 2010-04-02 |         1 | 
| 2010-04-03 |         0 | 
| 2010-04-04 |         1 | 
| 2010-04-05 |         0 | 
| 2010-04-06 |         0 | 
| 2010-04-07 |         0 | 
| 2010-04-08 |         2 | 
+------------+-----------+
7 rows in set (0.00 sec)

标签:mysql,sql,gaps-and-islands
来源: https://codeday.me/bug/20190515/1111178.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有