我的查询如下:
DECLARE @razem VARCHAR(MAX);
SELECT Ordering.orderID ,
Document.number,
(User_info.name +' '+ User_info.surname),
Ordering.dateStart,
Ordering.dateEnd ,
(
select COALESCE(' ',@razem)+sell_type.name as r
from Ordering_sell_type, Sell_type
where orderID = Ordering.orderID and
Ordering_sell_type.sell_typeID = sell_type.sell_typeID
) podz
FROM Ordering, User_info, Product_Document, Document, Document_type
WHERE Ordering.orderID = Product_document.orderID
AND Document.documentID = Document_type.documentID
AND Document.documentID = Product_document.documentID
AND Ordering.userID = User_info.userID
AND Ordering.isClosed = 1 AND Document_type.typeID = 1
GROUP BY Document.isitfiscal, Document.refDocID,
Document.number, Ordering.orderID, User_info.name,
User_info.surname, Ordering.dateStart,
Ordering.dateEnd , Ordering.isCLosed
ORDER BY Ordering.dateEnd
在COALESCE函数中,我想获得所选订单的所有付款类型 - 例如,orderID 123有payTypes =卡,现金,orderID有payTypes =现金。
问题是我想把它放在一个简单的行中作为主查询的最后一行,如: orderID,Document.number,UserInfo.name + surname,dateStart,dateEnd, - > card,cash&lt ;- 但在尝试上面的查询后我得到了错误:
Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
因为它返回多行。是否有可能在子查询中获得付款类型并返回为一个字符串?
答案 0 :(得分:5)
根据您使用的语法,我假设您使用的是SQL-Server,因此您可以使用SQL-Servers XML扩展来连接字符串。
SELECT Ordering.orderID,
Document.number,
[UserName] = User_info.name +' '+ User_info.surname,
Ordering.dateStart,
Ordering.dateEnd,
[podz] = STUFF(( SELECT DISTINCT ' ' + SellType.Name
FROM Ordering_Sell_Type
INNER JOIN Sell_Type
ON Sell_Type.sell_typeID = Ordering_Sell_Type.sell_typeID
WHERE Ordering.OrderID = Ordering_SellType.OrderId
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM Ordering
INNER JOIN User_Info
ON Ordering.UserID = User_Info.UserID
INNER JOIN ProductDocument
ON Ordering.OrderID = Product_Document.OrderID
INNER JOIN Document
ON Document.DocumentID = Product_Document.DocumentID
INNER JOIN Document_Type
ON Document_Type.DocumentID = Document.DocumentID
WHERE Ordering.IsClosed = 1
AND Document_Type.TypeID = 1
ORDER BY Ordering.dateEnd;
注意我已经用ANSI 92替换了所有ANSI 89连接,因为这是更现代的语法,并且generally accepted是更易读的选项(我说通常被接受,因为它当然是个人偏好和那里在Oracle优化ANSI89连接时,还有一些情况。)
修改强>
看过您的数据后,重复项来自Product_Document表,您可以使用以下方法删除它们:
SELECT Ordering.orderID,
Document.number,
[UserName] = User_info.name +' '+ User_info.surname,
Ordering.dateStart,
Ordering.dateEnd,
[podz] = STUFF(( SELECT DISTINCT ' ' + SellType.Name
FROM Ordering_Sell_Type
INNER JOIN Sell_Type
ON Sell_Type.sell_typeID = Ordering_Sell_Type.sell_typeID
WHERE Ordering.OrderID = Ordering_SellType.OrderId
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM Ordering
INNER JOIN User_Info
ON Ordering.UserID = User_Info.UserID
INNER JOIN
( SELECT DISTINCT OrderID, DocumentID
FROM Product_Document
) Product_Document
ON Ordering.OrderID = Product_Document.OrderID
INNER JOIN Document
ON Document.DocumentID = Product_Document.DocumentID
INNER JOIN Document_Type
ON Document_Type.DocumentID = Document.DocumentID
WHERE Ordering.IsClosed = 1
AND Document_Type.TypeID = 1
ORDER BY Ordering.dateEnd;
答案 1 :(得分:0)
这篇SO文章/答案很好地讨论了将一系列varchar行汇总/聚合到一个列中的不同方法,就像你在谈论https://stackoverflow.com/a/2410524/283895
答案 2 :(得分:0)
是。但这取决于您使用的RDBMS。
要在一行中生成数据列表,您必须使用特定于您使用的RDBMS的分析函数,或编写您自己的特定函数。
在oracle中:WM_CONCAT,LISTAGG或XMLAGG函数将多个共享相似数据的行转换为列表。
Coalese一次只能处理一行而不会合并行。
使用/语法各不相同。所以我建议根据你的RDBMS搜索这些术语。