将SQL中的多行选择到子查询中的一行中

将SQL中的多行选择到子查询中的一行中,sql,sql-server,coalesce,Sql,Sql Server,Coalesce,我有如下疑问: DECLARE @razem VARCHAR(MAX); SELECT Ordering.orderID , Document.number, (User_info.name +' '+ User_info.surname), Ordering.dateStart, Ordering.dateEnd , ( select COALESCE(' ',@

我有如下疑问:

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
在这个合并函数中,我想得到所选订单的所有支付类型——例如,orderid123的payTypes=Card,Cash,orderID的payTypes=Cash

问题是,我希望将它作为主查询的最后一行放在一行中,如:
orderID、Document.number、UserInfo.name+姓氏、dateStart、dateEnd、->card、cash根据您使用的语法,我假设您使用的是SQL Server,因此您可以使用SQL Server 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连接,因为这是更现代的语法,并且是更清晰的选项(我说这是普遍接受的,因为这当然是个人偏好,而且在某些情况下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;

这篇SO文章/答案很好地讨论了将一系列varchar行汇总/聚合为一列的不同方法,就像您所说的

是的。但这取决于您使用的RDBMS

为了生成一行中的数据列表,您必须使用特定于您使用的RDBMS的分析函数,或者编写自己的特定函数


在oracle:WM_CONCAT中,listag或XMLAGG函数将共享相似数据的多行转换为一个列表

Coalese一次只能工作一行,不合并行

  • 甲骨文:WM_CONCAT、Listag、XMLAGG
  • SQL SERVER:XMLpath
  • 我的SQL:Group_Concat

用法/语法各不相同。因此,我建议根据您的RDBMS搜索这些术语。

您使用的是哪种RDBMS?在oracle:WM_CONCAT中,listag或XMLAGG函数会将共享相似数据的多行转换为一个列表。Coalese一次只能工作一行,不合并行。在SQL server中,我相信也有类似的组合;我认为mySQL使用的是,如果我没有正确猜测DBMS,那么有许多其他方法可以回答,重复从何而来,每个订单是否有多个文档,其中文档类型为1?不,每个订单只有一个文档。就这样,订单只有在未关闭时才是订单。在我们关闭它(-order)之后,它就变成了文档(并且出现在文档表中),在查询中使用DISTINCT并没有什么真正的错误,但是通常最好隔离重复的源并在那里处理它们。找到它们的一个好方法是使用
SELECT*
运行相同的查询,并查看上面列出的列相同的行中的不同值。
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;