检查日期SQL Server之间的总计

时间:2014-07-15 23:41:46

标签: sql sql-server-2012

我在Microsoft SQL Server 2012中有一个问题。假设数据库中有四列:

Start_Date, end_date, client, percentage

两个记录的例子是

[1/31/14, 2/28/14, client a, 100]
[3/05/14, 5/01/14, client a, 100]

对于客户a,我想检查最早的start_date和最晚的结束日期之间每天的总百分比为100。在这个例子中,3/1 - 3/4不等于100.我希望客户端名称是输出。

有什么建议吗?

3 个答案:

答案 0 :(得分:0)

我会忽略这个百分比,因为它看起来并不相关(它不是100吗?)。你只是在寻找差距。如果您知道时间段内没有重叠,则可以这样做:

select client
from table a
where percentage = 100
group by client
having sum(datediff(day, start_date, end_date)) <> datediff(day, min(start_date), max(end_date));

如果存在重叠,则逻辑稍微困难一点,因为您必须对此进行测试。但是,您的问题并没有说明在这种情况下要做什么。

答案 1 :(得分:0)

有很多文章描述如何创建自己的日历表,我相信你需要一个。请注意,您没有告诉使用什么类型的SQL(MySQL,MS SQL,Oracle,其他......),因此您需要找到适合您的文章。或者,如果您不想要日历表,则可以使用递归CTE来生成日期范围。

在表格或CTE中显示日期后,请将现有表格加入到以下内容中:

SELECT
     d.client
   , cal.pkdate
   , sum(coalesce(d.percent,0)) as sum_pct
FROM MyCalendatTbl cal
LEFT JOIN MyExistingData d on cal.pkdate between d.start_date and d.end_date
GROUP BY
     d.client
   , cal.pkdate
HAVING
  sum(d.percent) <> 100

这将找到间隙和重叠

答案 2 :(得分:0)

使用函数LAG,可以在不使用日历表的情况下检查数据中的间隙和重叠

WITH Gaps AS (
  SELECT Start_Date, end_date, client, percentage
       , Last_EndDate = LAG(end_date, 1, Start_Date) 
                      OVER (PARTITION BY client ORDER BY Start_Date)
  FROM   Table1
)
SELECT DISTINCT client
FROM   Gaps
WHERE  DateDiff(d, Last_EndDate, Start_Date) NOT IN (0, 1)

SQLFiddle Demo

查询假定以下数据正确

2014-01-31, 2014-02-28, 'client a', 100
2014-03-01, 2014-05-01, 'client a', 100
2014-01-31, 2014-03-01, 'client b', 100
2014-03-01, 2014-05-01, 'client b', 100

客户端a作为具有相邻结束日期和开始日期的两行,客户端b作为相同的结束日期和开始日期。如果只有前者是正确的,则需要更改查询

WITH Gaps AS (
  SELECT Start_Date, end_date, client, percentage
       , Last_EndDate = LAG(end_date, 1, DateAdd(d, -1, Start_Date)) 
                      OVER (PARTITION BY client ORDER BY Start_Date)
  FROM   Table1
)
SELECT DISTINCT client
FROM   Gaps
WHERE  DateDiff(d, Last_EndDate, Start_Date) <> 1

SQLFiddle Demo