【问题标题】:Generate Dates starting from a date returned by a condition - SQL从条件返回的日期开始生成日期 - SQL
【发布时间】:2013-01-07 10:20:29
【问题描述】:

我之前问过的series of dates with a specified interval can be generated using a variable and a static date as per the linked question。但是,当有 where 子句生成开始日期时,dates generation 似乎停止并且只显示第一个间隔日期。我还检查了其他帖子,我发现 e.g. 1e.g. 2e.g. 3 显示为 static date 或使用 CTE.. 我正在寻找一个解决方案 没有 storedprocedures/functions...

这行得通:

SELECT DATE(DATE_ADD('2012-01-12', 
INTERVAL @i:=@i+30 DAY) ) AS dateO
FROM members, (SELECT @i:=0) r
where @i < DATEDIFF(now(), date '2012-01-12') 
;

这些不:

SELECT DATE_ADD(date '2012-01-12', 
INTERVAL @j:=@j+30 DAY) AS dateO, @j
FROM `members`, (SELECT @j:=0) s
where @j <= DATEDIFF(now(), date '2012-01-12') 
and mmid = 100
;

SELECT DATE_ADD(stdate, 
INTERVAL @k:=@k+30 DAY) AS dateO, @k
FROM `members`, (SELECT @k:=0) t
where @k <= DATEDIFF(now(), stdate)
and mmid = 100
;

预期结果:

与第一个查询结果相同,因为它开始生成日期为 stDatemmid=100

最好在ANSI SQL 中支持,因为Oracle has trunc and rownum given per this query with 14 votesPostGres 具有generatge_Series 功能。 我想知道这是MYSQL 中的错误还是限制


PS:我之前也问过类似的问题。它基于static date values,因为它基于基于条件的表列中的日期值。

【问题讨论】:

  • 如果您在 WHERE 子句中使用 and mmid = 100,您将获得从 mmid = 100 的行派生的单行。真的想做什么?显示两个日期之间每 30 天间隔的日期?
  • 我想为从开始日期到现在的每个成员生成 10 天的间隔。 30 天只是 10 天的一个例子。您可以在我的表格中看到每个成员的日期。因此,对于 10 个成员,我需要 10 个不同且单独的日期集,在我的情况下,每个开始日期都是唯一的。如果您需要进一步说明,请告诉我。我什至尝试使用通过选择进入查询设置的变量来分配开始日期。它只是不起作用。
  • @JW。您的 SQL 技能令人钦佩。你能分享一些关于如何快速使用 SQLFiddle 以及快速拍摄 qeries(包括非常容易到高级的)的技巧吗?您是在几个月内才拿起它,还是它是如何达到这个速度的:)?谢谢。

标签: sql date


【解决方案1】:

确保跨平台兼容性的最简单方法是使用日历表。最简单的形式

create table calendar (
  cal_date date primary key
);

insert into calendar values
('2013-01-01'),
('2013-01-02'); -- etc.

有很多方法可以生成插入日期。

您使用 WHERE 子句来选择行,而不是使用 WHERE 子句来生成行。要选择今年 10 月,只需

select cal_date
from calendar
where cal_date between '2013-10-01' and '2013-10-31';

它相当紧凑——365,000 行涵盖 1000 年。这应该涵盖了大多数业务场景。

如果需要跨平台的日期算术,可以加个计数栏。

drop table calendar;
create table calendar (
  cal_date date primary key,
  tally integer not null unique check (tally > 0)
);

insert into calendar values ('2012-01-01', 1); -- etc.

要选择以 30 天为间隔的所有日期,从 2012 年 1 月 12 日开始,到日历年年底结束,请使用

select cal_date
from calendar
where ((tally - (select tally
                 from calendar
                 where cal_date = '2012-01-12')) % 30 ) = 0;

cal_date
--
2012-01-12
2012-02-11
2012-03-12
2012-04-11
2012-05-11
2012-06-10
2012-07-10
2012-08-09
2012-09-08
2012-10-08
2012-11-07
2012-12-07

如果您的“mmid”列保证没有间隙(日历表的一个未说出口的要求),您可以使用“mmid”列代替我的“tally”列。

【讨论】:

  • 谢谢@Catcall。我会更新我的问题,说没有日历表:-) 即使有一个日历表,它也不适合这个问题,因为您的示例仍然使用static range 检索日期。我很想知道为什么查询无法根据条件生成给定日期的日期,这是一个有效的场景。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多