从包含月度条目的表生成日期跨度

时间:2015-10-26 14:47:02

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

我们假设我们在SQL Server 2012中有一个如下所示的表:

YYYYMM | Mbr_ID | Product_ID
----------------------------
201501 | 000001 | AA
201502 | 000001 | AA
201503 | 000001 | AB
201504 | 000001 | AA
201505 | 000001 | AA
201506 | 000001 | AA

会有多个成员,他们可能会多次切换产品,但绝不会在一个月内切换产品。

我希望将其转换为span表,如下所示:

CMonth_Start | CMonth_End | Mbr_ID | Product_ID
-----------------------------------------------
201501       | 201502     | 000001 | AA
201503       | 201503     | 000001 | AB
201504       | 201506     | 000001 | AA

如果我尝试使用MIN(YYYYMM)和MAX(YYYYMM)来做这件事,我只会得到第一个产品的外跨度(201501-201506)。我知道必须有某种方法可以做到这一点,我确信这很简单,但我现在无法想到它。我非常感谢大家给予我的任何帮助,感谢您的阅读!

2 个答案:

答案 0 :(得分:2)

您可以使用以下查询:

    var elems = document.getElementsByClassName('test');
    angular.forEach(elems, function (elem) {
        angular.element(elem).bind('click', (function (x) {
            return function () {
                console.log(x); //prints woohoo
                alert(this.innerHTML);
            }
        })('woohoo'));
    });

SELECT MIN(YYYYMM) AS CMonth_Start, MAX(YYYYMM) AS CMonth_End, Mbr_ID, Product_ID FROM ( SELECT Mbr_ID, Mbr_ID, Product_ID, ROW_NUMBER() OVER (PARTITION BY Mbr_ID ORDER BY YYYYMM) - ROW_NUMBER() OVER (PARTITION BY Mbr_ID, Product_ID ORDER BY YYYYMM) AS grp FROM mytable ) AS t GROUP BY Mbr_ID, Product_ID, grp 标识每个grp具有相同Product_ID值的连续记录的切片。在外部查询中使用此字段,我们可以Mbr_ID / MIN MAXYYYYMMProduct_ID值{。}}。

答案 1 :(得分:2)

要按顺序识别相同值的组,可以使用行号的差异:

select mbr_id, product_id, min(yyyymm) as month_start, max(yyyymm) as month_end
from (select t.*,
             (row_number() over (partition by mbr_id order by yyyymm) -
              row_number() over (partition by mbr_id, product_id order by yyyymm)
             ) as grp
      from t
     ) t
group by mbr_id, grp, product_id;

要了解其工作原理,只需运行子查询以查看grp值是什么样的。