Sql server 2008 r2 将两个文本/数字数据转换为范围
我试图将数据从两列(一列带有文本,一列带有数字)转换为一个范围 我已搜索,但无法找到适用于此所需解决方案的内容:Sql server 2008 r2 将两个文本/数字数据转换为范围,sql-server-2008-r2,Sql Server 2008 R2,我试图将数据从两列(一列带有文本,一列带有数字)转换为一个范围 我已搜索,但无法找到适用于此所需解决方案的内容: Table: ColumnA Nvarchar(50) ColumnB Int 表格样本: ColumnA ColumnB AA 1 AA 2 AA 3 AA 4 AA 5 AB 1 AB 2 AB 3 AB 4
Table:
ColumnA Nvarchar(50)
ColumnB Int
表格样本:
ColumnA ColumnB
AA 1
AA 2
AA 3
AA 4
AA 5
AB 1
AB 2
AB 3
AB 4
期望输出:
AA:1-5, AB:1-4
任何帮助都将不胜感激。请注意,我假设您提出此问题的原因是,您可能已经打破了范围,而不是简单地为每个列A寻找最小/最大列B
如果你问我,这类事情最好在中间层或直接在表示层的代码中处理。在查询中按(ColumnA,ColumnB)对行进行排序,然后在读取行时通过一次传递即可获得所需的结果—将当前值与前一行进行比较,并在ColumnA更改或ColumnB不相邻时输出一行
但是,如果您决心在SQL中执行此操作,则可以使用递归CTE。基本前提是将每一行与相邻行关联,并在继续操作时保留ColumnB的起始值。相邻行定义为具有相同ColumnA值和下一个ColumnB值(即前一行+1)的行 应该采取以下措施:
;with cte as (
select a.ColumnA, a.ColumnB, a.ColumnB as rangeStart
from myTable a
where not exists ( --make sure we don't keep 'intermediate rows' as start rows
select 1
from myTable b
where b.ColumnA = a.ColumnA
and b.ColumnB = a.ColumnB - 1
)
union all
select a.ColumnA, b.ColumnB, a.rangeStart
from cte a
join myTable b on a.ColumnA = b.ColumnA
and b.ColumnB = a.ColumnB + 1 --correlate with 'next' row
)
select ColumnA, rangeStart, max(ColumnB) as rangeEnd
from cte
group by ColumnA, rangeStart
根据你的样本数据
对于踢腿,.通过做一些数学运算,注意连续值的group by子句
DECLARE @Data table (ColumnA Nvarchar(50), ColumnB Int)
INSERT @Data VALUES
('AA', 1),
('AA', 2),
('AA', 3),
--('AA', 4),
('AA', 5),
('AB', 1),
('AB', 2),
('AB', 3),
('AB', 4)
;WITH Ordered AS
(
SELECT
ROW_NUMBER() OVER (PARTITION BY ColumnA ORDER BY ColumnB) AS Seq,
*
FROM @Data
)
SELECT
ColumnA,
CASE
WHEN 1 = 0 THEN ''
-- if the ColumnA only has 1 row, the display is 1-1? or just 1?
--WHEN MIN(ColumnB) = MAX(ColumnB) THEN CONVERT(varchar(10), MIN(ColumnB))
ELSE CONVERT(varchar(10), MIN(ColumnB)) + '-' + CONVERT(varchar(10), MAX(ColumnB))
END AS Range
FROM Ordered
GROUP BY
ColumnA,
ColumnB - Seq -- The math
ORDER BY ColumnA, MIN(ColumnB)
您能澄清输出应该是什么吗?是两行,还是一行两列或其他什么?最好弄清楚,如果列B对于每个列A都是连续的,那么解决方案会简单得多——只有一列输出,不幸的是,列B的数量之间可能会有差距