Chr*_*son 1 sql-server partitioning date
之前有人问过一个类似的问题,但我一直无法将这些答案调整到我的问题中。
我想在连续日期中查找行,其中另一列具有相同的值,并将其作为单个日期范围返回。
我尝试使用OVER和PARTITION BY以及 ROW_NUMBER() 来获得我需要的结果,但我对这些概念不够熟悉,无法找出正确的输出。
系统为 Microsoft SQL Server 2014。
鉴于:
CREATE TABLE EXCEPTIONS
(
ID NUMERIC(18) NOT NULL,
DATE DATE NOT NULL,
TYPE VARCHAR(20) NOT NULL,
VALUE VARCHAR(20),
);
Run Code Online (Sandbox Code Playgroud)
和数据:
INSERT INTO EXCEPTIONS VALUES
(17482, '2016-08-24', 'PRESSURE_EXCEPTION', 'Over'),
(17482, '2016-08-25', 'PRESSURE_EXCEPTION', 'Over'),
(17482, '2016-08-26', 'PRESSURE_EXCEPTION', 'Over'),
(17482, '2016-09-04', 'PRESSURE_EXCEPTION', 'Over'),
(17482, '2016-09-05', 'PRESSURE_EXCEPTION', 'Over'),
(17482, '2016-09-16', 'PRESSURE_EXCEPTION', 'Under'),
(17482, '2016-09-17', 'PRESSURE_EXCEPTION', 'Under'),
(17482, '2016-09-23', 'PRESSURE_EXCEPTION', 'Under'),
(17482, '2016-09-24', 'PRESSURE_EXCEPTION', 'Under'),
(17482, '2016-09-25', 'PRESSURE_EXCEPTION', 'Under'),
(17482, '2016-09-27', 'VOLUME_EXCEPTION', 'Low'),
(17482, '2016-09-28', 'VOLUME_EXCEPTION', 'Low')
Run Code Online (Sandbox Code Playgroud)
此查询的结果应该类似于
StartDate | EndDate | Type | Value
2016-08-24 | 2016-08-26 | 'PRESSURE_EXCEPTION' | 'Over'
2016-09-04 | 2016-09-05 | 'PRESSURE_EXCEPTION' | 'Over'
2016-09-16 | 2016-09-17 | 'PRESSURE_EXCEPTION' | 'Under'
2016-09-23 | 2016-09-25 | 'PRESSURE_EXCEPTION' | 'Under'
2016-09-27 | 2016-09-28 | 'VOLUME_EXCEPTION' | 'Low'
Run Code Online (Sandbox Code Playgroud)
SQLFiddle可用于更多数据
这是一个“差距和岛屿”问题。我拿了这个例子并根据你的情况调整了它。
DECLARE @TestData TABLE (
ID NUMERIC(18) NOT NULL
,[DATE] DATE NOT NULL
,[TYPE] VARCHAR(20) NOT NULL
,[VALUE] VARCHAR(20)
)
INSERT INTO @TestData VALUES
(17482, '2016-08-24', 'PRESSURE_EXCEPTION', 'Over'),
(17482, '2016-08-25', 'PRESSURE_EXCEPTION', 'Over'),
(17482, '2016-08-26', 'PRESSURE_EXCEPTION', 'Over'),
(17482, '2016-09-04', 'PRESSURE_EXCEPTION', 'Over'),
(17482, '2016-09-05', 'PRESSURE_EXCEPTION', 'Over'),
(17482, '2016-09-16', 'PRESSURE_EXCEPTION', 'Under'),
(17482, '2016-09-17', 'PRESSURE_EXCEPTION', 'Under'),
(17482, '2016-09-23', 'PRESSURE_EXCEPTION', 'Under'),
(17482, '2016-09-24', 'PRESSURE_EXCEPTION', 'Under'),
(17482, '2016-09-25', 'PRESSURE_EXCEPTION', 'Under'),
(17482, '2016-09-27', 'VOLUME_EXCEPTION', 'Low'),
(17482, '2016-09-28', 'VOLUME_EXCEPTION', 'Low')
;
WITH mycte
AS (
SELECT *
,DATEADD(DAY, - ROW_NUMBER() OVER (
PARTITION BY [Value] ORDER BY [Date]
), [Date]) AS grp
FROM @TestData
)
--select * from mycte --Uncomment to see the data from mycte
SELECT min([Date]) AS [From]
,max([Date]) AS [To]
,[Type]
,[value]
FROM mycte
GROUP BY [Type]
,[value]
,grp
ORDER BY [From];
Run Code Online (Sandbox Code Playgroud)
| From | To | Type | value |
|------------|------------|--------------------|-------|
| 2016-08-24 | 2016-08-26 | PRESSURE_EXCEPTION | Over |
| 2016-09-04 | 2016-09-05 | PRESSURE_EXCEPTION | Over |
| 2016-09-16 | 2016-09-17 | PRESSURE_EXCEPTION | Under |
| 2016-09-23 | 2016-09-25 | PRESSURE_EXCEPTION | Under |
| 2016-09-27 | 2016-09-28 | VOLUME_EXCEPTION | Low |
Run Code Online (Sandbox Code Playgroud)
OVER/PARTITION 逻辑基本上是将每一行分配给一个“组”,这样您就可以从每个组中挑选出MIN和MAX。如果您取消注释
select * from mycte(我按日期添加了一个订单)并从该部分到顶部运行脚本,您将看到每一行都被分配给一个组。
查看分配给“2016-08-23”的第一组行。的ROW_NUMBER日期“2016年8月24日”为1,所以DATEADD从“2016年8月24日”中减去1,以把该行中的组“2016年8月23日”。的ROW_NUMBER日期“2016年8月25日”为2,所以DATEADD从“2016年8月25日”中减去2把它在相同的组中的行号1等。
| ID | DATE | TYPE | VALUE | grp |
|-------|------------|--------------------|-------|------------|
| 17482 | 2016-08-24 | PRESSURE_EXCEPTION | Over | 2016-08-23 |
| 17482 | 2016-08-25 | PRESSURE_EXCEPTION | Over | 2016-08-23 |
| 17482 | 2016-08-26 | PRESSURE_EXCEPTION | Over | 2016-08-23 |
| 17482 | 2016-09-04 | PRESSURE_EXCEPTION | Over | 2016-08-31 |
| 17482 | 2016-09-05 | PRESSURE_EXCEPTION | Over | 2016-08-31 |
| 17482 | 2016-09-16 | PRESSURE_EXCEPTION | Under | 2016-09-15 |
| 17482 | 2016-09-17 | PRESSURE_EXCEPTION | Under | 2016-09-15 |
| 17482 | 2016-09-23 | PRESSURE_EXCEPTION | Under | 2016-09-20 |
| 17482 | 2016-09-24 | PRESSURE_EXCEPTION | Under | 2016-09-20 |
| 17482 | 2016-09-25 | PRESSURE_EXCEPTION | Under | 2016-09-20 |
| 17482 | 2016-09-27 | VOLUME_EXCEPTION | Low | 2016-09-26 |
| 17482 | 2016-09-28 | VOLUME_EXCEPTION | Low | 2016-09-26 |
Run Code Online (Sandbox Code Playgroud)
现在,这只是从每个组中拉取MIN和的问题MAX。
| 归档时间: |
|
| 查看次数: |
10164 次 |
| 最近记录: |