避免SQL Pivot返回重复的行

时间:2019-04-13 02:00:53

标签: sql sql-server pivot

我有以下SQL脚本,该脚本在PIVOT中返回重复值。如何将这些重复的记录合并到一行。

请检查下图显示的结果集。

SELECT *
FROM   (SELECT X.stockcode,
               X.description,
               X.pack,
               X.location,
               X.lname,
               X.qty,
               Y.stockcode AS StockCode2,
               y.periodname,
               Y.months,
               Y.saleqty
        FROM   (SELECT dbo.stock_items.stockcode,
                       dbo.stock_items.description,
                       dbo.stock_items.pack,
                       dbo.stock_loc_info.location,
                       dbo.stock_locations.lname,
                       dbo.stock_loc_info.qty
                FROM   dbo.stock_locations
                       INNER JOIN dbo.stock_loc_info
                               ON dbo.stock_locations.locno = dbo.stock_loc_info.location
                       LEFT OUTER JOIN dbo.stock_items
                                    ON dbo.stock_loc_info.stockcode = dbo.stock_items.stockcode
                WHERE  ( dbo.stock_items.status = 's' )) AS X
               LEFT OUTER JOIN (SELECT dbo.dr_invlines.stockcode,
                                       ( 12 + Datepart(month, Getdate()) - Datepart(month, dbo.dr_trans.transdate) ) % 12 + 1 AS Months,
                                       Sum(dbo.dr_invlines.quantity)                                                          AS SaleQty,
                                       dbo.period_status.periodname
                                FROM   dbo.dr_trans
                                       INNER JOIN dbo.period_status
                                               ON dbo.dr_trans.period_seqno = dbo.period_status.seqno
                                       LEFT OUTER JOIN dbo.stock_items AS STOCK_ITEMS_1
                                                       RIGHT OUTER JOIN dbo.dr_invlines
                                                                     ON STOCK_ITEMS_1.stockcode = dbo.dr_invlines.stockcode
                                                    ON dbo.dr_trans.seqno = dbo.dr_invlines.hdr_seqno
                                WHERE  ( STOCK_ITEMS_1.status = 'S' )
                                       AND ( dbo.dr_trans.transtype IN ( 1, 2 ) )
                                       AND ( dbo.dr_trans.transdate >= Dateadd(m, -6, Getdate()) )
                                GROUP  BY dbo.dr_invlines.stockcode,
                                          Datepart(month, dbo.dr_trans.transdate),
                                          dbo.period_status.periodname) AS Y
                            ON X.stockcode = Y.stockcode) z
       PIVOT (Sum(saleqty) FOR [months] IN ([1],[2],[3],[4],[5],[6])) AS pivoted  

enter image description here

1 个答案:

答案 0 :(得分:0)

编辑:我想念您的问题的根本原因是,因为包含了periodname列而导致重复。我将其保留为一般显示CTE使用情况的解决方案,因为如果您随后想要对数据透视结果进行额外的过滤/转换,它仍然很有用

一种方法是获取数据透视查询的结果,并通过SELECT DISTINCT查询运行它。

将您的数据透视查询包装为CTE,并使用它为下面的SELECT DISTINCT填充的示例(请注意:未经测试,但在我的SSMS中解析为有效)

WITH PivotResults_CTE (
    stockcode,
    description,
    pack,
    location,
    lname,
    qty,
    StockCode2,
    periodname,
    months,
    saleqty
)
AS (
    SELECT *
    FROM (
        SELECT X.stockcode
            ,X.description
            ,X.pack
            ,X.location
            ,X.lname
            ,X.qty
            ,Y.stockcode AS StockCode2
            ,y.periodname
            ,Y.months
            ,Y.saleqty
        FROM (
            SELECT dbo.stock_items.stockcode
                ,dbo.stock_items.description
                ,dbo.stock_items.pack
                ,dbo.stock_loc_info.location
                ,dbo.stock_locations.lname
                ,dbo.stock_loc_info.qty
            FROM dbo.stock_locations
            INNER JOIN dbo.stock_loc_info ON dbo.stock_locations.locno = dbo.stock_loc_info.location
            LEFT OUTER JOIN dbo.stock_items ON dbo.stock_loc_info.stockcode = dbo.stock_items.stockcode
            WHERE (dbo.stock_items.STATUS = 's')
            ) AS X
        LEFT OUTER JOIN (
            SELECT dbo.dr_invlines.stockcode
                ,(12 + Datepart(month, Getdate()) - Datepart(month, dbo.dr_trans.transdate)) % 12 + 1 AS Months
                ,Sum(dbo.dr_invlines.quantity) AS SaleQty
                ,dbo.period_status.periodname
            FROM dbo.dr_trans
            INNER JOIN dbo.period_status ON dbo.dr_trans.period_seqno = dbo.period_status.seqno
            LEFT OUTER JOIN dbo.stock_items AS STOCK_ITEMS_1
            RIGHT OUTER JOIN dbo.dr_invlines ON STOCK_ITEMS_1.stockcode = dbo.dr_invlines.stockcode ON dbo.dr_trans.seqno = dbo.dr_invlines.hdr_seqno WHERE (STOCK_ITEMS_1.STATUS = 'S')
                AND (
                    dbo.dr_trans.transtype IN (
                        1
                        ,2
                        )
                    )
                AND (dbo.dr_trans.transdate >= Dateadd(m, - 6, Getdate()))
            GROUP BY dbo.dr_invlines.stockcode
                ,Datepart(month, dbo.dr_trans.transdate)
                ,dbo.period_status.periodname
            ) AS Y ON X.stockcode = Y.stockcode
        ) z
    PIVOT(Sum(saleqty) FOR [months] IN (
                [1]
                ,[2]
                ,[3]
                ,[4]
                ,[5]
                ,[6]
                )) AS pivoted
)
SELECT DISTINCT *
FROM
    PivotResults_CTE
; 

还请注意,上面包含的sql看起来可能与原始sql略有不同,但这仅是因为我通过重新格式化程序来运行它以确保我理解它的结构。

换句话说,您的数据透视查询的基本CTE包装器是:

WITH PivotResults_CTE (
    Field1,
    Field2,
    ...
)
AS (
    YOUR_PIVOT_QUERY_HERE
)
SELECT DISTINCT *
FROM
    PivotResults_CTE
;