Избегайте SQL Pivot, возвращающего повторяющиеся строки

#sql #sql-server #pivot

#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  
 

введите описание изображения здесь

Комментарии:

1. В столбце PERIODNAME другое значение. каков ваш ожидаемый результат?

2. «Скармливайте» сводке только требуемые столбцы. Как намекает D-Shih, удалите PERIODNAME из вашего запроса.

3. Тогда я удалю столбец с именем периода

Ответ №1:

РЕДАКТИРОВАТЬ: я пропустил основную причину вашей проблемы, заключающуюся в включении столбца periodname, вызывающего предполагаемое дублирование. Я оставляю это как общее решение, показывающее использование CTE, потому что оно все равно может быть полезно, если вы захотите выполнить дополнительную фильтрацию / преобразование результатов вашего pivot

Один из способов — взять результаты сводного запроса и запустить его с помощью запроса 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, включенный в приведенное выше, может немного отличаться от вашего оригинала, но это только потому, что я прогнал его через переформатирование, чтобы убедиться, что я понял его структуру.

Другими словами, базовая оболочка CTE для вашего сводного запроса:

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