Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/84.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 Server:使用CTE作为子查询将行压缩为串联字符串_Sql_Sql Server_Common Table Expression - Fatal编程技术网

SQL Server:使用CTE作为子查询将行压缩为串联字符串

SQL Server:使用CTE作为子查询将行压缩为串联字符串,sql,sql-server,common-table-expression,Sql,Sql Server,Common Table Expression,我正在重写一个写得不好的应用程序的几个页面,我正在尝试将此逻辑作为子查询合并到主查询中,这样我就可以一下子获得所有数据,而不是像当前代码那样连接5万次 我从 DECLARE @combinedString NVARCHAR(MAX),@mds NVARCHAR(MAX) SELECT @combinedString = COALESCE(@combinedString + ', ', '') + serial, @mds = MDS FROM (aircra

我正在重写一个写得不好的应用程序的几个页面,我正在尝试将此逻辑作为子查询合并到主查询中,这样我就可以一下子获得所有数据,而不是像当前代码那样连接5万次

我从

DECLARE @combinedString NVARCHAR(MAX),@mds   NVARCHAR(MAX)

SELECT 
    @combinedString = COALESCE(@combinedString + ', ', '') + serial,
    @mds = MDS  
FROM 
    (aircraftserials 
LEFT JOIN  
    serialnums ON serialnums.ID = aircraftserials.Serialnum_ID) 
WHERE 
    (85 = aircraftserials.Aircraft_ID AND serial IS NOT NULL)
我想消除这些变量并将其作为子查询

我想我需要一个CTE;最终结果必须是

MDS, concatenated serials
我试过这篇文章,但还是不太明白

这是数据的样本

CREATE TABLE TestBed 
(
     Aircraft_ID INT, 
     Serial VARCHAR(50),
     MDS VARCHAR(50)
)

INSERT INTO TestBed (Aircraft_ID, Serial, MDS) 
VALUES (85, '56-1965', 'T-37B'),
       (85, '56-1967', 'T-37B'),
       (85, '56-3547', 'T-37B'),
       (85, '56-3577', 'T-37B'),
       (85, '57-2265', 'T-37B'),
       (85, '57-2272', 'T-37B'),
       (85, '58-1915', 'T-37B'),
       (85, '58-1925', 'T-37B'),
       (85, '59-0249', 'T-37B'),
       (85, '59-0273', 'T-37B'),
       (85, '59-0299', 'T-37B')

select * from TestBed

我想你不是在寻找一个CTE,而是一个带有字符串连接的聚合。在SQL Server中,可以使用XML的子查询
完成

SELECT tb1.aircraft_id,
       stuff((SELECT concat(', ', tb2.serial)
              FROM testbed tb2
              WHERE tb2.aircraft_id = tb1.aircraft_id
                    AND tb2.mds = tb1.mds
              FOR XML PATH ('')), 1, 2, '') serial,
       tb1.mds
       FROM testbed tb1
       GROUP BY tb1.aircraft_id,
                tb1.mds;


顺便说一句:如果每架飞机的mds总是相同的,那么它不应该在测试床上,而是在飞机表上。

我根据你的测试数据提出了一个递归CTE

;with ForceId as 
    (SELECT ROW_NUMBER() OVER(partition by MDS order by serial) as RN,* FROM TestBed),
    RECURS as
    (SELECT f.MDS,f.RN,f.Serial, cast(f.serial as nvarchar(max)) as x  FROM ForceId F WHERE F.RN = 1
     UNION ALL
     SELECT f2.mds,f2.rn, r.Serial,r.x  + ', ' + f2.Serial  FROM ForceId F2 
                    JOIN RECURS R
                    ON F2.mds = R.mds 
                    AND R.RN + 1 = F2.rn        
    )
    SELECT MDS, x  FROM 
            recurs r where r.rn = 
            (select max(r2.rn) from recurs r2 where r.MDS = r2.mds)

样本数据和期望的结果将非常有帮助。对代码应该做什么有一些了解。在示例查询中也使用适当的别名来显示哪个列来自哪个表,例如选择中的
serial
mds
列。我只需要帮助将CTE中的数据展平,我可以合并所有后来包含的样本数据。你想让合并后的字符串从一行增长到另一行,还是让飞机有一行,所有序列都在一个字符串中?让我把它插入主查询,我会让你知道它是否奏效