如何在MySQL中生成数据?
以下是我的SQL:如何在MySQL中生成数据?,mysql,sql,Mysql,Sql,以下是我的SQL: SELECT COUNT(id), CONCAT(YEAR(created_at), '-', MONTH(created_at), '-', DAY(created_at)) FROM my_table GROUP BY YEAR(created_at), MONTH(created_at), DAY(created_at) 我希望即使在没有创建ID的日子里也能显示一行。现在我错过了很多没有活动的日子 关于如何更改此查询以实现此目的,您有什么想法吗?众所周知,S
SELECT
COUNT(id),
CONCAT(YEAR(created_at), '-', MONTH(created_at), '-', DAY(created_at))
FROM my_table
GROUP BY YEAR(created_at), MONTH(created_at), DAY(created_at)
我希望即使在没有创建ID的日子里也能显示一行。现在我错过了很多没有活动的日子
关于如何更改此查询以实现此目的,您有什么想法吗?众所周知,SQL不善于返回数据库中没有的数据。您可以找到日期间隔的起始值和结束值,但获取所有日期很困难 解决方案是创建一个日历表,每个日期有一条记录,并将其连接到查询中 下面是一个假设在类型日期创建的_的示例:
SELECT calendar_date, COUNT(`id`)
FROM calendar LEFT OUTER JOIN my_table ON calendar.calendar_date = my_table.created_at
GROUP BY calendar_date
(我猜创建的时间实际上是DATETIME,所以你必须做更多的体操才能加入到表格中)。总体思路 MySQL中有两种主要的数据生成方法。一种是在运行查询时动态生成数据,另一种是将数据保存在数据库中,并在必要时使用它。当然,如果要经常运行查询,第二个将比第一个更快。但是,第二种方法需要数据库中的一个表,该表的唯一目的是生成缺少的数据。它还要求您具有足够的权限来创建该表 动态数据生成 这种方法涉及到创建
联合
s以生成一个伪表,该表可用于将实际表与。可怕且重复的查询是:
select aDate from (
select @maxDate - interval (a.a+(10*b.a)+(100*c.a)+(1000*d.a)) day aDate from
(select 0 as a 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) a, /*10 day range*/
(select 0 as a 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) b, /*100 day range*/
(select 0 as a 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) c, /*1000 day range*/
(select 0 as a 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) d, /*10000 day range*/
(select @minDate := '2001-01-01', @maxDate := '2002-02-02') e
) f
where aDate between @minDate and @maxDate
无论如何,这比看起来要简单。它使用10
数值生成派生表的笛卡尔积,因此结果将有10^X
行,其中X
是查询中派生表的数量。在本例中,有10000
天范围,因此您可以表示超过27
年的周期。如果需要更多,请向查询中添加另一个UNION
并更新间隔,如果不需要那么多,可以从派生表中删除UNION
或单个值。为了澄清这一点,您可以通过对@minDate
和@maxDate
变量应用带有WHERE
子句的筛选器来微调日期周期(但不要使用比您使用笛卡尔积创建的周期更长的周期)
静态数据生成
此解决方案将要求您在数据库中生成一个表。该方法与前一种方法类似。您必须首先将数据插入该表:从1
到X
的整数范围,其中X
是所需的最大范围。同样,如果您不确定,只需插入100000
值,就可以创建超过273
年的日范围。因此,一旦获得整数序列,就可以将其转换为如下所示的日期范围:
select '2012-01-01' + interval value - 1 day aDay from seq
having aDay <= '2012-01-05'
select (select min(aDate) from domainTable) + interval value - 1 day aDay
from seq
having aDay <= (select max(aDate) from domainTable)
这将生成一个包含所有所需天数的派生表(注意,我使用的是静态数据生成),并对我们的域表执行左联接
,因此所有天数都将显示,无论它们在我们的域表中是否有匹配的值。另请注意,count
应在具有null
值的字段上执行,因为这些值未被计数
需要考虑的注释
1) 这些查询可用于查询对代码执行微小更改的其他时间间隔(月、年)
2) 不必硬编码日期,您可以从域表中查询min
和max
值,如下所示:
select '2012-01-01' + interval value - 1 day aDay from seq
having aDay <= '2012-01-05'
select (select min(aDate) from domainTable) + interval value - 1 day aDay
from seq
having aDay <= (select max(aDate) from domainTable)
如您所见,查询的框架与前一个相同。唯一改变的是如何生成派生表allDays
。现在,派生表的生成方式也与我之前添加的略有不同。这是因为在示例filddle中,我只需要10
-天的范围。如您所见,它比添加1000
日范围更具可读性。下面是动态解决方案的示例,以便您也可以使用它
希望这有帮助 试验台:
create table testbed(id integer,在日期创建);
插入到测试床值中
(1, '2012-04-01'),
(1, '2012-04-30'),
(2, '2012-04-02'),
(3, '2012-04-03'),
(3, '2012-04-04'),
(4, '2012-04-04');
我还使用了任意_表
,这是我人工创建的,如下所示:
select '2012-01-01' + interval value - 1 day aDay from seq
having aDay <= '2012-01-05'
select (select min(aDate) from domainTable) + interval value - 1 day aDay
from seq
having aDay <= (select max(aDate) from domainTable)
创建表任意_表(id整数);
在任何_表中插入值(1)、(2)、(3)、(4)、(5)、(6)、(7)、(8)、(9)、(10);
插入到任意_表中,从任意_表中选择*重复此插入7-8次
您可以使用数据库中任何一个表,该表的行数超过max(created_dt)-min(created_dt)
范围,至少365行,覆盖一年
查询:
选择concat(年(博士日期),'-',月(博士日期),'-',日(博士日期)),
--或者,代替concat(),只需:dr.(u date)
计数(id)
从(
选择日期\u添加(r.mindt,dist day的间隔)\u日期,
@距离:=@dist+1天
从任何表t
加入(选择min(创建时)mindt,
最大值(在最大值处创建),
@距离:=0
从试验台)r
WHERE date_add(r.mindt,INTERVAL@dist day)在一个查询中执行此操作的方法:
选择COUNT(my_table.id)作为总计,
CONCAT(年(dates.ddate),“-”,月(dates.ddate),“-”,日(dates.ddate))
从(
--从2000-01-01(179年)开始创建“动态”65536天
选择日期添加(“2000-01-01”,时间间隔(b1.b+b2.b+b3.b+b4.b+b5.b+b6.b+b7.b+b8.b+b9.b+b10.b+b11.b+b12.b+b13.b+b14.b+b15.b+b16.b)天)作为起始日期
(选择0作为b联合选择1)b1,
(选择0作为b联合选择2)b2,
(选择0作为b联合选择4)b3,
(选择0作为b联合选择8)b4,
(选择0作为b联合选择16)b5,
(选择0作为b联合选择32)b6,
(选择