用于连续两周检查条目的SQL查询

时间:2014-07-30 12:26:21

标签: sql

我想构建一个返回连续两周输入的条目的查询。

例如:

Name  |  Country  |  Date
Name1 | Country1  | 2014-07-29 
Name2 | Country2  | 2014-08-08 
Name1 | Country2  | 2014-08-07

我希望能够选择连续两周输入的条目。在这种情况下,我的查询将只返回Name1。

我最近问了一个关于查询在两个不同日期输入的记录的类似问题,这就是我对此的看法:

SELECT Name
FROM Table
GROUP by Name
COUNT(DISTINCT Date) > 1

但是这会检查记录是否已插入多个日期,但并不是连续两周至少输入一次。

3 个答案:

答案 0 :(得分:1)

您还没有说过您正在使用的DBMS,并且“周”的处理方式不同。 Stack Overflow问题Getting week number of date in SQL是一个很好的起点,或http://users.atw.hu/sqlnut/sqlnut2-chp-4-sect-4.html的SQL2003标准,并在其中搜索EXTRACT。

但是使用SQL-Server,一个有效的例子就是

--Input your sample data
DECLARE @T TABLE (N varchar(50),   C varchar(50),  D  Date)
INSERT INTO @T VALUES('Name1', 'Country1', '2014-07-29'), ('Name2', 'Country2', '2014-08-08'), ('Name1', 'Country2', '2014-08-07')

--Code to search it for entries in consecutive weeks
SELECT DISTINCT T1.N FROM @T as T1 INNER JOIN @T as T2 ON T1.N = T2.N
WHERE (DATEPART(year, T1.D) * 52 + DATEPART(week, T1.D)) - (DATEPART(year, T2.D) * 52 + DATEPART(week, T2.D)) = 1

请注意,您确实需要使用周函数,因为星期一一周和同一周五的条目比一周的星期五和下周的星期一的订单更远。

另请注意,您不能使用本周,否则2005年1月第一周的参赛作品将与2006年1月第二周的参赛作品“匹配”,或者将在2004年12月的最后一周错过比赛。

答案 1 :(得分:0)

如果您对周的定义是“7天后”,那么您可以执行以下操作:

select t.name, t.date
from table t
where exists (select 1
              from table t2
              where t2.name = t.name and
                    t.date between t2.date + 7 and t2.date + 14 
             );

请注意,不同的数据库处理日期的方式不同,因此t.date + 7可能无法在所有数据库中使用。有一些类似的结构。

答案 2 :(得分:0)

如果没有更多信息我会对这个解决方案做出一些假设,但这里有一个使用t-SQL的袖口/粗略思想......至少是一个起点:

select a.name
,a.date 
FROM table a
INNER JOIN table a2 ON a.name = a2.name
WHERE a2.date >= DATEADD(dd,(7 - (DATEPART(dw,a.date)%7)) +1, a.date)
AND a2.date < DATEADD(dd, 7, (DATEADD(dd,(7 - (DATEPART(dw,a.date)%7)) +1, a.date)))

这假定您确实希望在第一周出现的条目然后在第二周出现,其中第二周是从下一个星期日到星期六(或者您决定定义为一周开始的任何一天)的任何一天。我相信这符合您的要求,并且比将下一周定义为&#39;&gt; = +7和&lt; = +14天&#39;更具体一些。我并没有说这有什么不妥,只是如果你希望一个星期五的条目和下一个星期一的条目被认为是连续的一对,它可能无法满足你的需求。

此示例获取您的日期,找到表示其所在星期几的整数,然后从7开始修改并减去该数字,以查找直到当天结束的天数。然后,使用该周末日期,我们可以添加一天来查找下一周的开始,并使用DATEADD函数添加7天来查找上限(第二周开始),给我们一个工作日期范围。这很好用,因为它总是与通过的日期相关,你不必担心传递日期的位置(在一周内)。在不利方面,它可能不是将成为一个表演冠军...所以根据使用量和体积,它可能会很慢。