我有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日的日期,我希望在一个月内列出所有日期。 我有一个解决方案,通过创建另一个表只用于添加日期,该表将在join_on上连接我的用户表并将给出总结果但我不想这样做,因为创建我需要创建和添加条目在日期表中,请建议采用不同的方法。
谢谢。
答案 0 :(得分:4)
使用GROUP BY可能更简单,然后在实际代码中添加缺少的日期(或迭代整个日期范围,如果查询结果中缺少日期则输出零)。
并非所有东西都必须在SQL中解决,而且很多东西在其他地方更容易解决。 :)
答案 1 :(得分:2)
有一种方法可以在纯SQL中执行此操作,但它有局限性。
首先你需要一个数字序列1,2,3 ... n作为行(假设select row from rows
返回)。
然后您可以在此处继续加入,并根据最小和最大之间的天数转换为日期。
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表 如果使用子查询,可以避免使用变量,为了便于阅读,我将其分解。
现在,问题是表rows
中的行数必须大于@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)
答案 2 :(得分:1)
SELECT * FROM TABLE WHERE DATE LIKE '4/%/10'
这将为您提供2010年4月的所有数据
类似地,你可以通过指定月份的数值来获得任何月份的数据,在这种情况下为4