简体   繁体   English

在 MySQL 中的 generate_series() 等效

[英]generate_series() equivalent in MySQL

I need to do a query and join with all days of the year but in my db there isn't a calendar table.我需要进行查询并加入一年中的所有日子,但在我的数据库中没有日历表。
After google-ing I found generate_series() in PostgreSQL.在 google-ing 之后,我在 PostgreSQL 中找到了generate_series() Does MySQL have anything similar? MySQL有没有类似的东西?

My actual table has something like:我的实际表有类似的东西:

date     qty
1-1-11    3
1-1-11    4
4-1-11    2
6-1-11    5

But my query has to return:但我的查询必须返回:

1-1-11    7
2-1-11    0
3-1-11    0
4-1-11    2
and so on ..

This is how I do it.我就是这样做的。 It creates a range of dates from 2011-01-01 to 2011-12-31 :它创建了从2011-01-012011-12-31的日期范围:

select 
    date_format(
        adddate('2011-1-1', @num:=@num+1), 
        '%Y-%m-%d'
    ) date
from 
    any_table,    
    (select @num:=-1) num
limit 
    365

-- use limit 366 for leap years if you're putting this in production

The only requirement is that the number of rows in any_table should be greater or equal to the size of the needed range (>= 365 rows in this example).唯一的要求是any_table 中的行应大于或等于所需范围的大小(在此示例中为 >= 365 行)。 You will most likely use this as a subquery of your whole query, so in your case any_table can be one of the tables you use in that query.您很可能会将它用作整个查询的子查询,因此在您的情况下any_table可以是您在该查询中使用的表之一。

Enhanced version of solution from @Karolis that ensures it works for any year (including leap years):来自@Karolis 的增强版解决方案,确保它适用于任何年份(包括闰年):

select date from (
    select
        date_format(
        adddate('2011-1-1', @num:=@num+1),
        '%Y-%m-%d'
    ) date
    from
        any_table,
    (select @num:=-1) num
    limit
        366
) as dt
where year(date)=2011

I was looking to this solution but without the "hardcoded" date, and I came-up with this one valid for the current year(helped from this answers ).我正在寻找这个解决方案,但没有“硬编码”日期,我想出了这个对当年有效的解决方案(从这个答案中得到帮助)。 Please note the请注意

where year(date)=2011

is not needed as the select already filter the date.不需要,因为选择已经过滤了日期。 Also this way, it does not matter which table(at least as stated before the table has at least 366 rows) is been used, as date is "calculated" on runtime.同样这样,使用哪个表(至少如表至少有 366 行之前所述)并不重要,因为日期是在运行时“计算”的。

 select date from (
    select
        date_format(
        adddate(MAKEDATE(year(now()),1), @num:=@num+1),
        '%Y-%m-%d'
    ) date
    from
        your_table,
    (select @num:=-1) num
    limit
        366 ) as dt

Just in case someone is looking for generate_series() to generate a series of dates or ints as a temp table in MySQL.以防万一有人正在寻找 generate_series() 来生成一系列日期或整数作为 MySQL 中的临时表。

With MySQL8 (MySQL version 8.0.27) you can do something like this to simulate:使用 MySQL8(MySQL 版本 8.0.27)你可以做这样的事情来模拟:

WITH RECURSIVE nrows(date) AS (
SELECT MAKEDATE(2021,333) UNION ALL 
SELECT DATE_ADD(date,INTERVAL 1 day) FROM nrows WHERE  date<=CURRENT_DATE
)
SELECT date FROM nrows;

Result:结果:

2021-11-29
2021-11-30
2021-12-01
2021-12-02
2021-12-03
2021-12-04
2021-12-05
2021-12-06

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM