Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 在自定义列中显示日期范围-间隙和孤岛_Sql_Sql Server_Sql Server 2008_Tsql_Gaps And Islands - Fatal编程技术网

Sql 在自定义列中显示日期范围-间隙和孤岛

Sql 在自定义列中显示日期范围-间隙和孤岛,sql,sql-server,sql-server-2008,tsql,gaps-and-islands,Sql,Sql Server,Sql Server 2008,Tsql,Gaps And Islands,我有一张这样的桌子: +------------+------+ | Date | Name | +------------+------+ | 2017-01-07 | A | | 2017-01-08 | A | | 2017-01-09 | A | | 2017-01-12 | A | | 2017-01-07 | B | | 2017-01-08 | B | | 2017-01-09 | B | +------------+-----

我有一张这样的桌子:

+------------+------+
|    Date    | Name |
+------------+------+
| 2017-01-07 | A    |
| 2017-01-08 | A    |
| 2017-01-09 | A    |
| 2017-01-12 | A    |
| 2017-01-07 | B    |
| 2017-01-08 | B    |
| 2017-01-09 | B    |
+------------+------+
我希望能够将其转化为以下内容:

+-------------------------+------+
|       Date Range        | Name |
+-------------------------+------+
| 2017-01-07 - 2017-01-09 | A    |
| 2017-01-07 - 2017-01-09 | B    |
| 2017-01-12              | A    |
+-------------------------+------+
代码将只查找连续日期的最小值和最大值,使用Name列对结果进行分组,然后在一列中以“to”和“from”字符串的形式列出最小值和最大值

我在尝试只列出连续日期时遇到问题。请注意,上面的第三个条目有自己的条目,因为它与前面条目中“A”的日期范围不连续

编辑:请注意:这是特定于SQL Server 2008的,它不允许使用滞后函数


编辑2: McNets提供的原始答案在SQL Server 2012上运行良好。我把它包括在这里,因为如果您使用SQL Server 2012以后的版本,它会更好

;WITH CalcDiffDays AS
(
    SELECT Date, Name,
    CONCAT (Name, CAST(DATEDIFF(DAY, LAG(Date, 1, Date - 1) OVER (PARTITION BY Name ORDER BY Name, Date), Date) AS VARCHAR(10))) AS NumDays
    FROM @tmpTable
)
SELECT CONCAT(CONVERT(VARCHAR(20), MIN(Date), 102), ' - ', CONVERT(VARCHAR(20), MAX(Date), 102)) AS [Data Range], Name
FROM CalcDiffDays
GROUP BY NumDays, Name;

首先,我在整个表中添加了一个行号

WITH RowN AS
(
    SELECT Date, Name, ROW_NUMBER() OVER (ORDER BY Name, Date) RN
    FROM #T
)
然后,我把这个表和它自己连接起来,只是为了计算日期之间的天数

,CalcDiffDays AS
(
    SELECT RowN.Date, RowN.Name,
        ISLAND = RowN.Name + 
        CASE  
           WHEN RowN.RN > 1 AND RowN.Name = R2.Name THEN CAST(DATEDIFF(day, R2.Date, RowN.Date) AS VARCHAR(20))
           ELSE '1'
        END
    FROM RowN
         LEFT JOIN RowN R2 ON R2.RN = RowN.RN-1
)
差距。相同名称的连续日期之间的间隔天数

岛屿。通过将名称添加到计算的天数

+---------------------+------+---------+
|         Date        | Name | NumDays |
+---------------------+------+---------+
| 07.01.2017 00:00:00 |   A  |    A1   |
+---------------------+------+---------+
| 08.01.2017 00:00:00 |   A  |    A1   |
+---------------------+------+---------+
| 09.01.2017 00:00:00 |   A  |    A1   |
+---------------------+------+---------+
| 12.01.2017 00:00:00 |   A  |    A3   |
+---------------------+------+---------+
| 07.01.2017 00:00:00 |   B  |    B1   |
+---------------------+------+---------+
| 08.01.2017 00:00:00 |   B  |    B1   |
+---------------------+------+---------+
| 09.01.2017 00:00:00 |   B  |    B1   |
+---------------------+------+---------+
第二部分:获取每个岛屿的最小和最大日期

WITH RowN AS
(
    SELECT Date, Name, ROW_NUMBER() OVER (ORDER BY Name, Date) RN
    FROM #T
)
,CalcDiffDays AS
(
    SELECT RowN.Date, RowN.Name,
        ISLAND = RowN.Name + 
        CASE  
           WHEN RowN.RN > 1 AND RowN.Name = R2.Name THEN CAST(DATEDIFF(day, R2.Date, RowN.Date) AS VARCHAR(20))
           ELSE '1'
        END
    FROM RowN
         LEFT JOIN RowN R2 ON R2.RN = RowN.RN-1
)    
SELECT CONVERT(VARCHAR(20), MIN(Date), 102) + ' - ' + CONVERT(VARCHAR(20), MAX(Date), 102) AS [Data Range], Name
FROM CalcDiffDays
GROUP BY ISLAND, Name
ORDER BY MIN(Date);

+-------------------------+------+
|        Data Range       | Name |
+-------------------------+------+
| 2017.01.07 - 2017.01.09 |   A  |
+-------------------------+------+
| 2017.01.07 - 2017.01.09 |   B  |
+-------------------------+------+
| 2017.01.12 - 2017.01.12 |   A  |
+-------------------------+------+

您可以在此处查看:

这显然是正确答案,可能与我的2012服务器重复。但是,在2008年的服务器(我需要的服务器)上,我遇到了这个错误:并行数据仓库(PDW)功能未启用。谷歌暗示这可能是服务器的一个错误?我认为这是使用了LAG,这在2008年是不可用的。如果你的表有一个唯一的标识符,有一个可能的解决方案。谢谢你的帮助,这很有效。我在上面添加了您的原始答案,因为它在SQL Server 2012及以后的版本中运行良好。