在SQL Server 2005中,我有一个包含如下所示数据的表:
WTN------------Date
555-111-1212 2009-01-01
555-111-1212 2009-01-02
555-111-1212 2009-01-03
555-111-1212 2009-01-15
555-111-1212 2009-01-16
212-999-5555 2009-01-01
212-999-5555 2009-01-10
212-999-5555 2009-01-11
从此我想提取WTN,Min(日期),Max(日期)扭曲我想也打破每当有差距时日期,所以从上面的数据来看,我的结果应该是这样的:
WTN------------ MinDate---- MaxDate
555-111-1212 2009-01-01 2009-01-03
555-111-1212 2009-01-15 2009-01-16
212-999-5555 2009-01-01 2009-01-01
212-999-5555 2009-01-10 2009-01-11
答案 0 :(得分:8)
为什么每个人都这么死,不能使用桌子来做这种事情?数字表或日历表占用这么小的空间,如果足够引用,可能在内存中。您还可以使用ROW_NUMBER()轻松地导出数字表。使用数字表可以帮助理解查询。但这是一个不那么直截了当的例子,一段时间我从Plamen Ratchev那里捡到的一个技巧,希望它有所帮助。
DECLARE @wtns TABLE
(
WTN CHAR(12),
[Date] SMALLDATETIME
);
INSERT @wtns(WTN, [Date])
SELECT '555-111-1212','2009-01-01'
UNION ALL SELECT '555-111-1212','2009-01-02'
UNION ALL SELECT '555-111-1212','2009-01-03'
UNION ALL SELECT '555-111-1212','2009-01-15'
UNION ALL SELECT '555-111-1212','2009-01-16'
UNION ALL SELECT '212-999-5555','2009-01-01'
UNION ALL SELECT '212-999-5555','2009-01-10'
UNION ALL SELECT '212-999-5555','2009-01-11';
WITH x AS
(
SELECT
[Date],
wtn,
part = DATEDIFF(DAY, 0, [Date])
+ DENSE_RANK() OVER
(
PARTITION BY wtn
ORDER BY [Date] DESC
)
FROM @wtns
)
SELECT
WTN,
MinDate = MIN([Date]),
MaxDate = MAX([Date])
FROM
x
GROUP BY
part,
WTN
ORDER BY
WTN DESC,
MaxDate;
答案 1 :(得分:0)
你的问题与INTERVAL TYPES和一个名为PACKED NORMAL FORM的关系有关。
“时间数据和关系模型”中讨论了这些问题。
不要指望任何SQL系统真正帮助您解决此类问题。
尽管有一些教程系统,唯一能为这些问题提供体面支持的DBMS,我所知道的,也是我自己的。没有链接,因为我不想在这里做太多的“插件”。
答案 2 :(得分:0)
您可以通过GROUP BY
检测边界来执行此操作:
WITH Boundaries
AS (
SELECT m.WTN
,m.Date
,CASE WHEN p.Date IS NULL THEN 1
ELSE 0
END AS IsStart
,CASE WHEN n.Date IS NULL THEN 1
ELSE 0
END AS IsEnd
FROM so1590166 AS m
LEFT JOIN so1590166 AS p
ON p.WTN = m.WTN
AND p.Date = DATEADD(d, -1, m.Date)
LEFT JOIN so1590166 AS n
ON n.WTN = m.WTN
AND n.Date = DATEADD(d, 1, m.Date)
WHERE p.Date IS NULL
OR n.Date IS NULL
)
SELECT l.WTN
,l.Date AS MinDate
,MIN(r.Date) AS MaxDate
FROM Boundaries l
INNER JOIN Boundaries r
ON r.WTN = l.WTN
AND r.Date >= l.Date
AND l.IsStart = 1
AND r.IsEnd = 1
GROUP BY l.WTN
,l.Date