【问题标题】:Comma-separated List of Results逗号分隔的结果列表
【发布时间】:2015-02-19 10:44:26
【问题描述】:

我有一个相当基本的查询,它基本上为每个客户返回一个SUM 总发票行净额,其中给出了一定的折扣。

作为其中的一部分,我想以逗号分隔列表的形式返回每个折扣适用的发票编号。

这是必不可少的,因为它被输入到另一个只接受这种格式数据的软件中。

我可以在 Excel 中格式化,因为这是数据最终的位置,但我宁愿直接在查询中进行。

试图使用FOR XML PATH 函数来执行此操作让我头晕目眩。

下面是当前查询,它返回每个折扣组、客户、折扣百分比以及总和

发票编号字段为 invoice_header.ih_number

SELECT  variant_discount_group.vdg_node_path AS 'Discount Group' ,
        customer_detail.cd_statement_name AS 'Customer Name' ,
        invoice_line_item.ili_discount_percent AS 'Discount' ,
        SUM(( CASE WHEN invoice_header.ih_credit = 1 THEN -1
                   ELSE 1
              END ) * invoice_line_item.ili_qty) AS 'Qty' ,
        SUM(( CASE WHEN invoice_header.ih_credit = 1 THEN -1
                   ELSE 1
              END ) * invoice_line_item.ili_net) AS 'Total Net'
FROM    invoice_header
        JOIN invoice_line_item ON invoice_line_item.ili_ih_id = invoice_header.ih_id
        JOIN variant_detail ON variant_detail.vad_id = invoice_line_item.ili_vad_id
        JOIN variant_setting ON variant_setting.vas_vad_id = variant_detail.vad_id
        JOIN customer_detail ON customer_detail.cd_id = invoice_header.ih_cd_id
        LEFT JOIN variant_discount_group ON variant_discount_group.vdg_id = variant_setting.vas_vdg_id
WHERE   invoice_header.ih_datetime BETWEEN @DateFrom
                                   AND     @DateTo
        AND ISNULL(variant_discount_group.vdg_node_path, '') LIKE @VDGroup
        + '%'
        AND invoice_line_item.ili_discount_percent BETWEEN @DiscFrom
                                                   AND    @DiscTo
GROUP BY variant_discount_group.vdg_node_path ,
        customer_detail.cd_statement_name ,
        invoice_line_item.ili_discount_percent
ORDER BY variant_discount_group.vdg_node_path ,
        customer_detail.cd_statement_name ,
        invoice_line_item.ili_discount_percent

【问题讨论】:

  • 能否提供样本数据

标签: sql sql-server tsql


【解决方案1】:

试试这个

WITH    cte
          AS ( SELECT   variant_discount_group.vdg_node_path AS [Discount Group] ,
                        customer_detail.cd_statement_name AS [Customer Name] ,
                        invoice_line_item.ili_discount_percent AS [Discount] ,
                        ( CASE WHEN invoice_header.ih_credit = 1 THEN -1
                               ELSE 1
                          END ) * invoice_line_item.ili_qty AS [Qty] ,
                        ( CASE WHEN invoice_header.ih_credit = 1 THEN -1
                               ELSE 1
                          END ) * invoice_line_item.ili_net AS [Total Net] ,
                        invoice_header.ih_number AS [invoice]
               FROM     invoice_header
                        JOIN invoice_line_item ON invoice_line_item.ili_ih_id = invoice_header.ih_id
                        JOIN variant_detail ON variant_detail.vad_id = invoice_line_item.ili_vad_id
                        JOIN variant_setting ON variant_setting.vas_vad_id = variant_detail.vad_id
                        JOIN customer_detail ON customer_detail.cd_id = invoice_header.ih_cd_id
                        LEFT JOIN variant_discount_group ON variant_discount_group.vdg_id = variant_setting.vas_vdg_id
               WHERE    invoice_header.ih_datetime BETWEEN @DateFrom
                                                   AND     @DateTo
                        AND ISNULL(variant_discount_group.vdg_node_path, '') LIKE @VDGroup
                        + '%'
                        AND invoice_line_item.ili_discount_percent BETWEEN @DiscFrom
                                                              AND
                                                              @DiscTo
             )
    SELECT  a.[Discount Group] ,
            a.[Customer Name] ,
            a.[Discount] ,
            SUM(a.[Qty]) AS Qty ,
            SUM(a.[Total Net]) AS [Total Net] ,
            SUBSTRING(( SELECT  ', ' + CONVERT(VARCHAR, b.[invoice])
                        FROM    (SELECT DISTINCT 
                                        [invoice],
                                        [Discount Group], 
                                        [Customer Name], 
                                        [Discount]
                                 FROM cte) AS b
                        WHERE   a.[Discount Group] = b.[Discount Group]
                                AND a.[Customer Name] = b.[Customer Name]
                                AND a.[Discount] = b.[Discount]
                      FOR
                        XML PATH('')
                      ), 2, 1000) AS [List of invoices]
    FROM    cte AS a
    GROUP BY a.[Discount Group] ,
            a.[Customer Name] ,
            a.[Discount]
    ORDER BY a.[Discount Group] ,
            a.[Customer Name] ,
            a.[Discount]

【讨论】:

  • 运行速度快,非常感谢。比我的尝试好多了。
  • 其实,一件事。如果同一折扣组中的 2 个项目在一张发票上,则发票编号在子字符串中重复。
【解决方案2】:

我不知道性能问题,但您可以创建一个返回 VARCHAR 的函数。在您的选择语句中调用该函数,并作为参数提供您的发票编号参考。

在函数中,您将有一个针对所有发票编号行的光标,并对其进行迭代并连接到返回值中。

这可能是快速、肮脏和资源密集型的。

【讨论】:

  • 很遗憾,我无法在数据库上创建函数。
  • 考虑一下,您可能可以旋转 invoicenumber 的行,然后将它们连接到您的选择中。 [链接]technet.microsoft.com/de-de/library/…
  • 我不知道会有多少个发票号码。可能是 1,也可能是 50。
  • 好的,所以请在 www.sqlfiddle.com 上创建一个示例,谢谢。
猜你喜欢
  • 2010-10-14
  • 1970-01-01
  • 2018-03-09
  • 1970-01-01
  • 1970-01-01
  • 2021-11-17
相关资源
最近更新 更多