我有一个sql(transact sql - SQL server 2012),用于从具有有效地址的表(Customer)中获取客户名称(来自表详细信息):
Select Customer.Name, Details.Address
from Customer
left outer join Details on Details.Customer = Customer.Name
这用于每次从db服务器发回每个客户的每个记录(名称)行。没有提取多个记录。
最近我需要修改这个sql文本,以便获取他们根据数据库借用的书籍的名称,该书籍保存在另一个表格(Lending)中。现在脚本看起来像:
Select Customer.Name, Details.Address, Lending.BookName
from Customer
left outer join Details on Details.Customer = Customer.Name
left outer join Lending on Lending.CustomerName = Customer.Name
它正确地返回记录,但现在我遇到了问题。由于客户可以借阅多本图书,因此返回的数据会为同一客户显示多行,显示多个图书名称。根据我的软件规范,我需要为每个客户获取一行,在那一行中,我需要将所有书名附加在一列中。 有人可以帮我解决这个问题:如何在一个列中附加同一记录的多个数据,例如:
Name Address BookName
Somdip XX Brief History of Time,Headfirst SQL,Headfirst C#
而不是
Name Address BookName
Somdip XX Brief History of Time
Somdip XX Headfirst SQL
Somdip XX Headfirst C#
...
答案 0 :(得分:3)
我将上面的sql文本与'where'和'order by'子句一起使用,如:
SELECT Name,
Address ,
Split.a.value('.', 'VARCHAR(100)') BookName
FROM (SELECT Name,
Address ,
Cast ('<M>' + Replace(BookName, ',', '</M><M>') + '</M>' AS XML) AS Data
FROM [table] where ID = '1' order by Name) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
它给了我一个错误:ORDER BY子句在视图,内联函数,派生表,子查询和公用表表达式中无效,除非还指定了TOP,OFFSET或FOR XML。
答案 1 :(得分:0)
试试这个:
SELECT Name,
Address ,
Split.a.value('.', 'VARCHAR(100)') BookName
FROM (SELECT Name,
Address ,
Cast ('<M>' + Replace(BookName, ',', '</M><M>') + '</M>' AS XML) AS Data
FROM [table]) AS A
CROSS APPLY Data.nodes ('/M') AS Split(a)
答案 2 :(得分:0)
虽然我认为这通常是一个坏主意 - 在单个单元格中返回多个数据项 - 有很多方法可以解决它,但存在不同的性能问题。