【问题标题】:using a boolean condition count the months that have the condition sql使用布尔条件计算具有条件 sql 的月份
【发布时间】:2017-05-26 21:32:41
【问题描述】:

所以我有一个这样的表:

---id---datetime---month---active
    1   2016-12-01  Dec-16  0
    1   2016-12-02  Dec-16  1
    1   2017-01-28  Jan-17  1
    1   2017-02-03  Feb-17  0
    1   2017-02-24  Feb-17  0
    1   2017-03-05  Mar-17  0
    1   2017-03-24  Mar-17  1
    1   2017-04-02  Apr-17  1
    1   2017-04-25  Apr-17  1
    1   2017-05-02  May-17  1
    1   2017-05-28  May-17  0

我想要这样的结果:

---id---monthCount---Active
    1       1          0
    1       2          1
    1       2          0
    1       3          1
    1       1          0

该表确实有超过 1 个id

现在我只是使用分区和idactivedatetime 排序来获取最小日期和最大日期之间的差异,但这给了我第一次到1 以及当它最终变为 0 时。我希望通过 active 的每次更改将其详细分开。

我怎样才能做到这一点?

【问题讨论】:

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


    【解决方案1】:

    在 sql server 2012+ 中,你可以像这样使用LAG

    DECLARE @SampleData AS TABLE
    (
        id int,
        [datetime] datetime,
        active bit
    )
    
    
    ;WITH temp AS
    (
        SELECT   sd.id,
              sd.active, 
              sd.[datetime],
              lag(sd.active) over(PARTITION BY sd.id ORDER BY sd.datetime) AS previousActive,
              lag(sd.id) over( ORDER BY sd.id, sd.datetime) AS previousId
        FROM @SampleData sd
    )
    ,temp1 AS
    (
        SELECT *, 
              sum(CASE WHEN t.previousActive IS NULL OR t.previousActive != t.active OR t.id != t.previousId THEN 1 
                 ELSE 0 END) 
              OVER(PARTITION BY t.id ORDER BY t.[datetime]) AS groupid
        FROM temp t
    )
    SELECT t.id, count(DISTINCT month(t.datetime)) AS monthCount, t.active  
    FROM temp1 t
    GROUP BY id, t.groupid, t.active
    

    演示链接:http://rextester.com/SJZ16279

    【讨论】:

      【解决方案2】:

      您可以使用不同的行号来识别组(这是一个间隙和孤岛问题)。那么最终的解决方案就需要count(distinct):

      select id, count(distinct month) as monthcount, active
      from (select t.*,
                   row_number() over (partition by id order by month, active) as seqnum_i,
                   row_number() over (partition by id, active order by month) as seqnum_ia
            from t
           ) t
      group by id, active, (seqnum_i - seqnum_ia);
      

      这是假设数据按 id、month、active 排序——这是问题中数据的排序。最好有一列清楚地定义行的排序顺序。

      【讨论】:

      • 括号是什么?由于语法不正确,当我尝试运行代码时出现错误,我从未见过这样的分组,你能解释一下吗?是不是搞错了?
      猜你喜欢
      • 2019-06-09
      • 2020-05-02
      • 2023-04-01
      • 2014-08-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-29
      • 2014-10-25
      • 2013-02-26
      相关资源
      最近更新 更多