T-SQL查询,将多行的列合并为单个列

4

我看到了一些使用COALESCE和FOR XML的示例(似乎是更好的解决方案)来实现我要做的事情。但我无法完全掌握语法。

这是我的代码(我将只列出关键字段):

Table                    Fields
------                   -------------------------------
Requisition              ID, Number
IssuedPO                 ID, Number
Job                      ID, Number
Job_Activity             ID, JobID (fkey)
RequisitionItems         ID, RequisitionID(fkey), IssuedPOID(fkey), Job_ActivityID (fkey)

我需要一个查询,每行列出一个Requisition及其相关的Jobs和IssuedPOs。(Requisition编号以“R-”开头,Job编号以“J-”开头)
例如: R-123 | "PO1; PO2; PO3" | "J-12345; J-6780"
当然,Adam!这里有一个返回多行的查询。我必须使用外连接,因为并非所有的Requisitions都有分配给Jobs和/或IssuedPOs的RequisitionItems(在这种情况下,它们的fkey ID将为空)。
SELECT DISTINCT Requisition.Number,  IssuedPO.Number, Job.Number
        FROM Requisition
        INNER JOIN RequisitionItem on RequisitionItem.RequisitionID = Requisition.ID
        LEFT OUTER JOIN Job_Activity on RequisitionItem.JobActivityID = Job_Activity.ID
        LEFT OUTER JOIN Job on Job_Activity.JobID = Job.ID
        LEFT OUTER JOIN IssuedPO on RequisitionItem.IssuedPOID = IssuedPO.ID

查询不是做这种事情的最佳场所:你想要的违反了 SQL 的关系性质。你可以在应用程序代码或 Transact-SQL 存储过程代码中进行分组。 - 9000
虽然我同意这不是 SQL 中理想的操作,但我无法看出在存储过程中执行会更“好”(除非您转而使用临时表或内存表,否则查询语法将完全相同)。 - Adam Robinson
@adam-robinson:在TSQL中,您可以使用游标循环和可变变量来帮助将多个行组装成一个字符串。您可以创建一个函数,执行整个详细查询并将其打包到一个字符串中,并在主查询中使用它。 - 9000
@9000:我的意思是,在这里使用存储过程并没有什么特别“好”的地方,与在单个查询中执行相比。无论如何,对于像他所寻找的字符串连接,通常使用FOR XML更好(并且具有不需要任何实际过程代码的好处),即使它有点难以理解。 - Adam Robinson
你的申请和工作之间的关系对我来说不太明显。也许你应该发布一个查询示例,以便在单独的行中获取所需数据,然后有人可以提供基于FOR XML的查询来连接值并将结果减少到每个申请一行。 - Adam Robinson
1个回答

4

以下是使用子查询的一种方法:

select  'R-' + cast(r.number as varchar(32)) as RequisitionNumber
,       (
        select  'PO' + CAST(ip.number as varchar(32)) + ';'
        from    IssuedPO ip
        join    RequisitionItems ri
        on      ip.id = ri.IssuedPOID
        where   ri.RequisitionID = r.id
        for xml path('')
        ) as POList
,       (
        select  'J-' + CAST(j.number as varchar(32)) + ';'
        from    Job j
        join    Job_Activity ja
        on      j.id = ja.JobID
        join    RequisitionItems ri
        on      ri.Job_ActivityID = ja.id
        where   ri.RequisitionID = r.id
        for xml path('')
        ) as JobList
from    Requisition r

我会试一下,谢谢。你不必加上“R-”和“PO-”,那只是为了清晰明了。 :) - Shayne
如果你使用了 report,记得使用强制类型转换,否则它会返回无效的数据类型。 - LeSteelBox

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接