SQL 来识别缺失的一周

发布于 2024-08-16 14:41:52 字数 435 浏览 9 评论 0原文

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

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。

I have a database table with the following structure -

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

Week_End is a datetime column, and the date increments by 7 days with each new entry.

What I want is a SQL statement that will identify if there is a week missing in the sequence. So, if the table contained the following data -

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

The query would return 2009-11-15.

Is this possible? I am using SQL Server 2008, btw.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

泪是无色的血 2024-08-23 14:41:52

您已经接受了答案,所以我想您不需要这个,但无论如何我都快完成了它,它有一个所选解决方案所没有的优点:它不需要每年更新。它是这样的:

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 列的存在。

You've already accepted an answer so I guess you don't need this, but I was almost finished with it anyway and it has one advantage that the selected solution doesn't have: it doesn't require updating every year. Here it is:

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)

It is based on Andemar's solution, but handles the changing year too, and doesn't require the existence of the Sales column.

鹿港小镇 2024-08-23 14:41:52

连接表本身以搜索连续行:

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
)

这应该返回没有下一周的任何周。

Join the table on itself to search for consecutive rows:

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
)

This should return any weeks without a next week.

飘过的浮云 2024-08-23 14:41:52

假设您的“week_end”日期始终是一周中的星期日,您可以尝试使用 CTE - 一个通用表表达式,列出 2009 年的所有星期日,然后对您的表执行外连接。

表中缺少的所有行在选择中的“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

Assuming your "week_end" dates are always going to be the Sundays of the week, you could try a CTE - a common table expression that lists out all the Sundays for 2009, and then do an outer join against your table.

All those rows missing from your table will have a NULL value for their "week_end" in the select:

;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
美煞众生 2024-08-23 14:41:52

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

/* 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 子查询。

I know this has already been answered, but can I suggest something really simple?

/* 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)
;

If you know the range you want to look over, you don't need to use the MIN/MAX subquery in the CTE.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文