我有一个结果,可以从我的数据库中查询一系列值:
Start End
----- ---
1 3
5 6
137 139
通过这些,我需要在数据库中查询该范围内的记录,这些记录可能会返回如下内容:
Id Name
----- ------
1 foo
2 bar
3 baz
Id Name
----- ------
5 foo
6 baz
Id Name
----- ------
137 foo
138 bar
139 baz
我想将这些结果分组,保留任何id范围,因为它们与同一事物相关。例如,1-3与137-139相同,因此它的计数为2,但当然,'range'可以是2:
RangeStart RangeEnd Count
---------- -------- -----
137 139 2
5 6 1
另请注意,订单应更改分组,因此foo / bar / baz与foo / baz / bar不同。
如何实现这一目标?
编辑:我有开始结果(开始,结束),我只关心最终结果(RangeStart,RangeEnd,Count)。我实际上并不需要中间结果,我只是用它们作为解释。
答案 0 :(得分:3)
以下是两个问题:
设置:
DECLARE @Tags TABLE (
TagID INT,
Tag VARCHAR(3)
)
INSERT @Tags
SELECT 1, 'Foo' UNION ALL
SELECT 2, 'Bar' UNION ALL
SELECT 3, 'Baz' UNION ALL
SELECT 4, 'Foo' UNION ALL
SELECT 5, 'Bar' UNION ALL
SELECT 6, 'Baz'
DECLARE @Ranges TABLE (
StartRange INT,
EndRange INT
)
INSERT @Ranges
SELECT 1,3 UNION ALL
SELECT 2,3 UNION ALL
SELECT 3,4 UNION ALL
SELECT 4,6
查询显示第一个范围和结果:
/* Get the first start and end ranges with a match and */
/* the total number of occurences of that match */
SELECT
StartRange,
EndRange,
Total
FROM (
SELECT
StartRange,
EndRange,
Csv,
ROW_NUMBER() OVER (PARTITION BY Csv ORDER BY StartRange ASC) AS RowNum,
ROW_NUMBER() OVER (PARTITION BY Csv ORDER BY StartRange DESC) AS Total
FROM (
/* For each range and its associated Tag values, */
/* Concatenate the tags together using FOR XML */
/* and the STUFF function */
SELECT
StartRange,
EndRange,
(
SELECT STUFF(
(SELECT ',' + Tag
FROM @Tags WHERE TagID BETWEEN r.StartRange AND r.EndRange
ORDER BY TagID
FOR XML PATH('')),1,1,'')
) AS Csv
FROM @Ranges r
) t1
) t2
WHERE RowNum = 1
ORDER BY StartRange, EndRange
/* Results */
StartRange EndRange Total
----------- ----------- -----
1 3 2
2 3 1
3 4 1
查询以显示连接的字符串和总计:
/* Get the concatenated tags and their respective totals */
SELECT
Csv,
COUNT(*) AS Total
FROM (
/* For each range and its associated Tag values, */
/* Concatenate the tags together using FOR XML */
/* and the STUFF function */
SELECT
StartRange,
EndRange,
(
SELECT STUFF(
(SELECT ',' + Tag
FROM @Tags WHERE TagID BETWEEN r.StartRange AND r.EndRange
ORDER BY TagID
FOR XML PATH('')),1,1,'')
) AS Csv
FROM @Ranges r
) t1
GROUP BY Csv
ORDER BY Csv
/* Results */
Csv Total
------------ -----------
Bar,Baz 1
Baz,Foo 1
Foo,Bar,Baz 2
字符串连接方法由Jeremiah Peschka提供