用于识别缺失周的SQL

时间:2009-12-30 22:23:24

标签: sql sql-server sql-server-2008 gaps-and-islands

我有一个具有以下结构的数据库表 -

Week_End      Sales
2009-11-01    43223.43
2009-11-08     4324.23
2009-11-15    64343.23
...

Week_End是日期时间列,每个新条目的日期增加7天。

我想要的是一个SQL语句,它将识别序列中是否缺少一周。因此,如果该表包含以下数据 -

Week_End      Sales
2009-11-01    43223.43
2009-11-08     4324.23
2009-11-22    64343.73    
...

查询将返回2009-11-15。

这可能吗?我正在使用SQL Server 2008,顺便说一句。

4 个答案:

答案 0 :(得分:2)

将表连接到自身以搜索连续的行:

select a.*
from YourTable a
left join YourTable b
    on datepart(wk,b.Week_End) = datepart(wk,a.Week_End) + 1
-- No next week
where b.sales is null 
-- Not the last week
and datepart(wk,a.Week_End) <> (
    select datepart(wk,max(Week_End)) from YourTable
)

这应该在没有下周的情况下返回任何星期。

答案 1 :(得分:2)

你已经接受了答案,所以我猜你不需要这个,但我几乎完成了它,它有一个优势,所选择的解决方案没有:它不需要每年更新。这是:

SELECT T1.*
FROM Table1 T1
LEFT JOIN Table1 T2
ON T2.Week_End = DATEADD(week, 1, T1.Week_End)
WHERE T2.Week_End IS NULL
AND T1.Week_End <> (SELECT MAX(Week_End) FROM Table1)

它基于Andemar的解决方案,但也处理变化的年份,并且不需要存在Sales列。

答案 2 :(得分:1)

假设您的“week_end”日期总是一周的星期日,您可以尝试一个CTE - 一个公用表表达式,列出2009年的所有星期日,然后针对您的表进行外部联接。 / p>

表格中缺少的所有行都会在select中的“week_end”中显示NULL值:

;WITH Sundays2009 AS
(
    SELECT CAST('20090104' AS DATETIME) AS Sunday
    UNION ALL
    SELECT  
       DATEADD(DAY, 7, cte.Sunday)
    FROM  
       Sundays2009 cte 
    WHERE  
       DATEADD(DAY, 7, cte.Sunday) < '20100101'
)
SELECT
    sun.Sunday 'Missing week end date'
FROM
    Sundays2009 sun
LEFT OUTER JOIN     
    dbo.YourTable tbl ON sun.Sunday = tbl.week_end
WHERE
    tbl.week_end IS NULL

答案 3 :(得分:1)

我知道这已经得到了解答,但我可以提出一些非常简单的建议吗?

/* First make a list of weeks using a table of numbers (mine is dbo.nums(num),  starting with 1) */
WITH AllWeeks AS (
  SELECT DATEADD(week,num-1,w.FirstWeek) AS eachWeek
  FROM 
    dbo.nums
    JOIN
    (SELECT MIN(week_end) AS FirstWeek, MAX(week_end) as LastWeek FROM yourTable) w
    ON num <= DATEDIFF(week,FirstWeek,LastWeek)
)
/* Now just look for ones that don't exist in your table */
SELECT w.eachWeek AS MissingWeek
FROM AllWeeks w
WHERE NOT EXISTS (SELECT * FROM yourTable t WHERE t.week_end = w.eachWeek)
;

如果您知道要查看的范围,则无需在CTE中使用MIN / MAX子查询。