select语句给出一系列没有任何表的日期?

时间:2017-11-12 23:50:26

标签: mysql datetime

如果我有一个带有ZERO表的MySQL数据库。是否有可以返回结果的SQL语句:

+------------+
| date       |
+------------+
| 2017-06-01 |
| 2017-06-02 |
| 2017-06-03 |
| 2017-06-04 |
etc.... to any end date I want
+------------+

我想要这个的原因是因为我希望能够动态生成这样的表来帮助我在不同的数据库中进行一些查询。

4 个答案:

答案 0 :(得分:1)

在MariaDB中,您可以使用built-in seq table来执行此操作。例如,此查询将返回从2017年11月1日开始的100天

SELECT '2017-11-01' + INTERVAL seq.seq DAY AS sequential_day FROM seq_0_to_99 seq

在MySQL中,您需要参与一些猴子业务以获得一系列没有表格的数字。这个丑陋的小查询生成从零到15,625的数字。

SELECT A.N + 5*(B.N + 5*(C.N + 5*(D.N + 5*(E.N + 5*(F.N))))) AS seq
  FROM (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS A
  JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS B
  JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS C
  JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS D
  JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS E
  JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS F

您可以将其用作子查询来生成日期序列。

select '2017-11-01' + INTERVAL seq.seq DAY AS sequential_day
  from (
    SELECT A.N + 5*(B.N + 5*(C.N + 5*(D.N + 5*(E.N + 5*(F.N))))) AS seq
      FROM (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS A
      JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS B
      JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS C
      JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS D
      JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS E
      JOIN (SELECT 0 AS N UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4) AS F
       ) AS seq
 where seq.seq <= 99

它不是很优雅。事实上,它很难看。但它运作正常。

或者您可以自己制作日期表并使用它。

答案 1 :(得分:0)

您可以使用子查询声明第一个日期然后递增它,如下所示:

SELECT  @date := DATE_ADD(@date, INTERVAL 1 DAY) AS dates 
FROM mysql.help_relation , (
    SELECT @date:= DATE_SUB('2017-06-01', INTERVAL 1 DAY)) d 
    WHERE @date BETWEEN @date AND DATE_SUB('2017-06-04', INTERVAL 1 DAY
);

答案 2 :(得分:0)

一种方法是创建一个循环并插入。注意我并不热衷于使用“date”作为列名,因为它在查询中太混乱了。还建议将日期用作主键。

delimiter \\
## Create the calendar table.
CREATE TABLE calendar (
    cal_date date primary key
);
\\ 

## accepts a date range
CREATE PROCEDURE create_calendar(IN startdate date, IN enddate date)
BEGIN
    SET @x = 0;
    WHILE (startdate + INTERVAL @x DAY) < enddate DO
        ## Insert another row
        INSERT INTO calendar (cal_date) VALUES (startdate + INTERVAL @x DAY);
        SET @x = @x + 1;
    END WHILE;
END
\\

## populate the calendar table with wanted range 
## nb the enddate is NOT included in the table

CALL create_calendar('2017-01-01','2017-02-01');
\\
select * from calendar;
\\

如果表中需要更多日期,请使用所需范围重新运行该过程(但日历表中不得存在这些日期)。

源于如何Create a Tally Table in MySQL

答案 3 :(得分:0)

我认为您可以通过Stored ProceduresInline Tables

来完成
drop procedure if exists timer;
CREATE PROCEDURE timer()   
BEGIN
    DECLARE i INT DEFAULT 1;
    declare d date default now();
    drop table B;
    create table B (id date); 
    WHILE (d<='2017-11-23') DO
        insert into B values(d);
        set d = CURRENT_DATE()+i;
        set i = i+1;
    END WHILE;
    select * from B;
END;

如果您需要SP

,请拨打此CALL timer();

注意我在MYSQL中不是专家,我依靠这些答案来撰写这些答案(:所以您也可以从中受益,compare dates in mysql,{ {3}},Inline tables in mysql以及MySQL functions

同样注意您可以在存储过程中使用IN参数作为目标日期