在SQL中迭代思考日期

时间:2013-10-02 07:38:31

标签: mysql sql iteration

我有一个数据表1看起来有点像:

Record# Date        Person
1       12/12/2012  Tom
2       01/02/2013  Tom
3       10/02/2013  Tom
4       02/01/2013  John
5       04/01/2014  John
6       30/06/2010  Mary
7       30/06/2011  Mary
8       30/06/2012  Mary
9       30/07/2012  Mary

和另一个表2,我们有每个人的注册日期

Person  RegisterDate   MaxRecord
Tom     15/12/2011     100
John    01/01/2013     10
Mary    16/06/2010     50

在table1中添加记录之前,我需要检查Person的年度记录数(table1)是否低于该Person的MaxRecord数(table2)。按年度,我的意思是startDate =注册日期和endDate =注册日期+ 1年,而不是Januray 1st到12月31日。

如果我想为Mary添加记录,我想编写SQL,它会给我以下输出:

StartDate   EndDate     CountRecord
16/06/2010  15/06/2011    1
16/06/2011  15/06/2012    1
16/06/2012  15/06/2013    2

一旦构建了这个输出,我就可以测试是否允许新记录(对于Person)的日期。

有人可以给我一些线索,教程链接或一些帮助吗?

1 个答案:

答案 0 :(得分:0)

对于以下我假设你已经有一个数字表,如果你没有数字表,那么我建议你先制作一个,但是如果你不想那么你就可以{{3 }}

您可以通过将您的注册日期表(RegDate)与您的数字表交叉加入来获取所有边界的列表:

SELECT  r.Person, 
        DATE_ADD(r.RegisterDate, INTERVAL n.Number YEAR) PeriodStart,
        DATE_ADD(r.RegisterDate, INTERVAL n.Number + 1 YEAR) PeriodEnd,
        n.Number
FROM    RegDate r
        CROSS JOIN Numbers n;

这给出了一个表格(仅适用于汤姆并添加WHERE n.Number <= 3;作为示例):

Person  PERIODSTART   PERIODEND   NUMBER
Tom     15/12/2011    15/12/2012    0
Tom     15/12/2012    15/12/2013    1
Tom     15/12/2013    15/12/2014    2
Tom     15/12/2014    15/12/2015    3

create a number list on the fly

然后您需要将其加入到其他日期(T)的表中以进行计数:

SELECT  r.Person,
        DATE_ADD(r.RegisterDate, INTERVAL n.Number YEAR) StartDate,
        DATE_ADD(DATE_ADD(r.RegisterDate, INTERVAL n.Number + 1 YEAR), INTERVAL -1 DAY) EndDate,
        COUNT(T.Record) AS `CountRecord`
FROM    RegDate r
        CROSS JOIN Numbers n
        LEFT JOIN T
            ON T.Person = r.Person
            AND T.Date >= DATE_ADD(r.RegisterDate, INTERVAL n.Number YEAR)
            AND T.Date < DATE_ADD(r.RegisterDate, INTERVAL n.Number + 1 YEAR)
WHERE   DATE_ADD(r.RegisterDate, INTERVAL n.Number YEAR) <= CURRENT_TIMESTAMP
AND     r.Person = 'Mary'
GROUP BY r.Person, R.RegisterDate, n.Number;

给出最终结果:

PERSON  STARTDATE   ENDDATE     COUNTRECORD
Mary    2010-06-16  2011-06-15      1
Mary    2011-06-16  2012-06-15      2
Mary    2012-06-16  2013-06-15      1
Mary    2013-06-16  2014-06-15      0

<强> Example on SQL Fiddle

我已使用此行将结果限制在StartDate小于今天的位置

WHERE   DATE_ADD(r.RegisterDate, INTERVAL n.Number YEAR) <= CURRENT_TIMESTAMP

您可以根据需要明显更改