将序列号转换为单列,SQL中缺少值

问题描述 投票:1回答:1

我有一个站点的示例ID列表,格式为:Sitename,Sample Number,以便给定站点有n个样本号。例如,数据可能是:

site1 | 1
site1 | 2

等任意n。

使用以下作为类似示例,下面的数据将从最后一个select语句中得到答案:

CREATE TABLE #SiteWithId(SiteId VARCHAR(50), SampleNumber INT)

INSERT INTO #SiteWithId
(
    SiteId,
    SampleNumber
)
values 
(   'test', -- SiteId - varchar(50)
    1  -- SampleNumber - int
    ),
    ('test',2),
    ('test',3),
    ('test',4),
    ('test',6),
    ('test',7)

    SELECT * FROM #SiteWithId
    DROP TABLE #SiteWithId
    --the answer
    SELECT 'test', '1-4,6-7'

请注意,缺少的项目会在最终答案中创建一个中断。

我知道我可以循环遍历C#中的数据集并创建这样的项目。但有没有人知道只使用sql创建这样的值,所以我可以吐出报告所需的值?我想我也可以在sql中做一个循环,但我害怕它不可扩展,因为那不是sql的目的。

除了sql或c#中的循环之外,还有更好的方法吗?

sql sql-server
1个回答
5
投票

这是一个依赖于窗口函数的解决方案。记录的SampleNumber与具有相同ROW_NUMBER()的记录组中的SiteName之间的差异为您提供了它所属的组。然后,外部查询聚合每个组:

SELECT SiteName, CONCAT(MIN(SampleNumber), '-', MAX(SampleNumber)) SampleRange
FROM (
    SELECT 
        SiteName, 
        SampleNumber, 
        ROW_NUMBER() OVER(PARTITION BY SiteName ORDER BY SampleNumber) rn
    FROM mytable
) x
GROUP BY SiteName, (SampleNumber - rn)

Demo on DB Fiddle

样本数据:

SiteName | SampleNumber
:------- | -----------:
site1    |            1
site1    |            2
site1    |            3
site1    |            5
site1    |            6
site1    |            8
site1    |            9
site1    |           10

结果:

SiteName | SampleRange
:------- | :----------
site1    | 1-3        
site1    | 5-6        
site1    | 8-10       

如果您希望在一个记录中连接每个站点的所有范围,则可以添加另一级别的聚合并使用STRING_AGG()(自SQL Server 2017以来可用):

SELECT SiteName, STRING_AGG(SampleRange,',') SampleRange
FROM (
    SELECT SiteName, CONCAT(MIN(SampleNumber), '-', MAX(SampleNumber)) SampleRange
    FROM (
        SELECT 
            SiteName, 
            SampleNumber, 
            ROW_NUMBER() OVER(PARTITION BY SiteName ORDER BY SampleNumber) rn
        FROM mytable
    ) x
    GROUP BY SiteName, (SampleNumber - rn)
) y
GROUP BY SiteName

Demo

SiteName | SampleRange 
:------- | :-----------
site1    | 1-3,5-6,8-10
© www.soinside.com 2019 - 2024. All rights reserved.