如果Value连续两个月出现,则在sql

时间:2018-01-19 04:23:46

标签: sql-server tsql sql-server-2012

我想连续几个月检查ID,如果连续两个月出现相同的ID,那么只考虑第一个月的ID。 如果ID不是连续的月份,则显示按开始日期月份分组的不同ID。(我们仅考虑开始日期) 例如,ID 1出现在1月1月和2月的开始日期,然后1月份该ID的明显计数为1,ID 2和3的计数如何为 出现在1月和3月以及2月和5月Resp,现在我想在1月和3月看到这个不同的ID。 当前数据

表1:

ID    StartDate      EndDate
1     2017-01-12     2017-01-28
1     2017-01-19     2017-01-28
1     2017-01-29     2017-02-11
1     2017-02-01     2017-02-11
1     2017-02-19     2017-02-24
2     2017-01-12     2017-01-28
2     2017-01-19     2017-01-28
2     2017-03-09     2017-03-20
3     2017-02-12     2017-02-28
3     2017-02-19     2017-02-28
3     2017-05-05     2017-05-29
3     2017-05-09     2017-05-29

我尝试了下面的逻辑bt我知道我在这里缺少什么。

select t.* from Table1 t
join Table1 t t1
on t1.ID=t.ID 
and datepart(mm,t.StartDate)<> datepart(mm,t1.StartDate)+1

预期结果:

DistinctCount     StartDateMonth(In Numbers)
   1                 1(Jan)
   2                 1(Jan)
   2                 3(March)
   3                 2(Feb)
   3                 5(May)

感谢任何帮助!

5 个答案:

答案 0 :(得分:2)

这是我的解决方案。对此的想法是:

1)将所有日期舍入到该月的第一天,然后使用(ID,StartDateRounded)的不同数据集。从您的数据集中,结果应如下所示:

ID     StartDateRounded

1      2017-01-01
1      2017-02-01
2      2017-01-01
2      2017-03-01
3      2017-02-01
3      2017-05-01

2)从此统一数据集中,按ID查找没有上个月记录的所有记录(这意味着它不是连续的月份,因此是新数据点的开头)。这是您的最终数据集

with DatesTable AS 
(
  SELECT DISTINCT ID
    ,DATEADD(month,DateDiff(month,0,StartDate),0) StartDateRounded
    ,DATEADD(month,DateDiff(month,0,StartDate)+1,0) StartDateRoundedPlusOne
  FROM Table1
)
SELECT t1.ID, DatePart(month,t1.StartDateRounded) AS StartDateMonth
  FROM DatesTable t1
    LEFT JOIN DatesTable t2
      ON t1.ID = t2.ID
        AND t1.StartDateRounded = t2.StartDateRoundedPlusOne
WHERE t2.ID IS NULL; --Verify no record exists for prior month

sqlfiddler以供参考。如果有帮助,请告诉我

答案 1 :(得分:1)

只需要利用内部查询的lag来比较行之间的值,并在中间查询中应用有问题的逻辑,然后进行最终选择。

/*SAMPLE DATA*/
create table #table1
    (
        ID int not null
        , StartDate date not null
        , EndDate date null
    )

insert into #table1
values (1, '2017-01-12', '2017-01-28')
    , (1, '2017-01-19', '2017-01-28')
    , (1, '2017-01-29', '2017-02-11')
    , (1, '2017-02-01', '2017-02-11')
    , (1, '2017-02-19', '2017-02-24')
    , (2, '2017-01-12', '2017-01-28')
    , (2, '2017-01-19', '2017-01-28')
    , (2, '2017-03-09', '2017-03-20')
    , (3, '2017-02-12', '2017-02-28')
    , (3, '2017-02-19', '2017-02-28')
    , (3, '2017-05-05', '2017-05-29')
    , (3, '2017-05-09', '2017-05-29')

/*ANSWER*/

--Final Select
select c.ID
, c.StartDateMonth
from (
    --Compare record values to rule a record in/out based on OP's logic
    select b.ID
    , b.StartDateMonth
    , case when b.StartDateMonth = b.StartDateMonthPrev then 0 --still the same month?
           when b.StartDateMonth = b.StartDateMonthPrev + 1 then 0 --immediately prior month?
           when b.StartDateMonth = 1 and b.StartDateMonthPrev = 12 then 0 --Dec/Jan combo
           else 1
      end as IncludeFlag
    from (
        --pull StartDateMonth of previous record into current record
        select a.ID
        , datepart(mm, a.StartDate) as StartDateMonth
        , lag(datepart(mm, a.StartDate), 1, NULL) over (partition by a.ID order by a.StartDate asc) as StartDateMonthPrev
        from #table1 as a
        ) as b
    ) as c
where 1=1
and c.IncludeFlag = 1

<强>输出:

+----+----------------+
| ID | StartDateMonth |
+----+----------------+
|  1 |              1 |
|  2 |              1 |
|  2 |              3 |
|  3 |              2 |
|  3 |              5 |
+----+----------------+

答案 2 :(得分:0)

尝试以下查询,

SELECT  ID,MIN(YEARMONTH) AS  YEARMONTH
FROM    (
        SELECT  ID
                ,YEAR([StartDate])*100+MONTH([StartDate])       AS YEARMONTH
                ,LAG(YEAR([StartDate])*100+MONTH([StartDate])) 
                                            OVER(ORDER BY ID)   AS PREVYEARMONTH
                ,ROW_NUMBER() OVER(ORDER BY ID)                 AS ROW_NO
        FROM    @Table1
        GROUP BY ID,((YEAR([StartDate])*100)+MONTH([StartDate]))
)   AS T
GROUP BY ID
    ,(CASE WHEN YEARMONTH - PREVYEARMONTH > 1 THEN ROW_NO ELSE 0 END)
ORDER BY ID

输出:

ID  YEARMONTH
1   201701
2   201701
2   201703
3   201702
3   201705

答案 3 :(得分:0)

谢谢大家。大多数逻辑似乎都有效..但我只是尝试了下面的一个而且我对thiis很好。

SELECT t1.ID, DatePart(month,t1.Startdate) AS StartDateMonth
  FROM DatesTable t1
    LEFT JOIN DatesTable t2
      ON t1.ID = t2.ID
        AND DatePart(month,t1.Startdate)  = DatePart(month,t2.Startdate)+1
WHERE t2.ID IS NULL;

再次感谢

答案 4 :(得分:-1)

好的,我在没有检查的情况下写了我的第一个查询,相信它会正常工作。这是我的更新版本,应该比其他解决方案更快

{{1}}