Sql server: соединение, столбцы с данными, удаление столбцов без

У меня есть две таблицы, LYEAR и CYEAR:

[SKU],[Title],[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12]

Столбцы [SKU],[Title],[1],[2],[3],[4],[5],[6],[7],[8] заполняются информацией из таблицы CYEAR и [SKU],[Title],[9],[10],[11],[12] из таблицы LYEAR.

Как мне объединить две таблицы, чтобы столбцы со значениями NULL были отброшены, оставив мне одну строку для каждого SKU?

Я зашел так далеко:

WITH LYEAR_ORG ([SKU],[Title],[QTY],[DATE]) AS 
(
    SELECT 
        T1.ItemNumber, T1.ItemTitle, (SUM(T2.nqty)) AS [UNITS], 
        CONVERT(VARCHAR(2), (MONTH(T3.dProcessedOn)))
    FROM 
        StockItem T1
    LEFT OUTER JOIN 
        OrderItem T2 ON T1.pkstockItemId = T2.fkStockItemID_processed
    LEFT JOIN 
        [Order] T3 ON T3.pkOrderID = T2.fkOrderID
    WHERE   
        (YEAR(T3.dProcessedOn)) = (YEAR(getdate())-1) 
        AND (MONTH(T3.dProcessedOn)) > (MONTH(getdate())-1)
    GROUP BY 
        T1.ItemNumber, T1.ItemTitle, 
        CONVERT(VARCHAR(2), (MONTH(T3.dProcessedOn)))
),
CYEAR_ORG ([SKU],[Title],[QTY],[DATE]) AS 
(
    SELECT T1.ItemNumber, T1.ItemTitle, (SUM(T2.nqty)) AS [UNITS], CONVERT(varchar(2),(MONTH(T3.dProcessedOn)))
    FROM StockItem T1
    LEFT OUTER JOIN OrderItem T2 ON T1.pkstockItemId = T2.fkStockItemID_processed
    LEFT JOIN [Order] T3 ON T3.pkOrderID = T2.fkOrderID
    WHERE   (YEAR(T3.dProcessedOn)) = (YEAR(getdate())-1) 
            AND (MONTH(T3.dProcessedOn)) < (MONTH(getdate()))
    GROUP BY T1.ItemNumber, T1.ItemTitle, CONVERT(varchar(2),(MONTH(T3.dProcessedOn)))
    ),

LYEAR ([SKU],[Title],[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12]) AS (
    SELECT *
    FROM LYEAR_ORG
    PIVOT ( MAX(QTY) FOR DATE in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])) as LYEAR_ORDERS
    ),

CYEAR ([SKU],[Title],[1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12]) AS (
    SELECT *
    FROM CYEAR_ORG
    PIVOT ( MAX(QTY) FOR DATE in ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12])) as CYEAR_ORDERS
    )

SELECT * FROM LYEAR
UNION ALL
SELECT * FROM CYEAR

Я не могу использовать INSERT INTO, так как это ограничение платформы Linnworks, над которой я работаю, это SQL Server.

Столбцы 1-8 LYEAR имеют значение все NULL, как и CYEAR 9-12?

Eric Brandt 13.09.2018 18:26

Да, это правильно. Но, конечно, это изменится по мере изменения текущего месяца. Не статично. Итак, в следующем месяце столбцы 1-9 LYEAR будут NULL.

Stuart 13.09.2018 18:34
0
2
54
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Если исходить из предположения, что столбцы 1-8 LYEAR все NULL, как и CYEAR 9-12, то JOIN с тонной COALESCE, а не UNION доставит вас туда, куда вы хотите. Однако, если в каких-либо столбцах есть значения для обоих лет, это будет изменено.

SELECT
  l.[SKU]
 ,l.[Title]
 ,COALESCE(l.[1], c.[1]) AS [1]
 ,COALESCE(l.[2], c.[2]) AS [2]
 ,COALESCE(l.[3], c.[3]) AS [3]
 ,COALESCE(l.[4], c.[4]) AS [4]
 ,COALESCE(l.[5], c.[5]) AS [5]
 ,COALESCE(l.[6], c.[6]) AS [6]
 ,COALESCE(l.[7], c.[7]) AS [7]
 ,COALESCE(l.[8], c.[8]) AS [8]
 ,COALESCE(l.[9], c.[9]) AS [9]
 ,COALESCE(l.[10], c.[10]) AS [10]
 ,COALESCE(l.[11], c.[11]) AS [11]
 ,COALESCE(l.[12], c.[12]) AS [12]
FROM
  LYEAR AS l
  JOIN
    CYEAR AS c
      ON
      c.SKU = l.SKU
      AND c.Title = l.Title;

Вот решение, которое позволит иметь данные как в LYEAR, так и в CYEAR и переключаться с одного на другой в зависимости от месяца в году:

            SELECT  SKU,
                    Title,
                    CASE    WHEN DATEPART(MM, GETDATE()) > 1
                                THEN LYEAR.1
                                ELSE CYEAR.1
                                END,
                    CASE    WHEN DATEPART(MM, GETDATE()) > 2
                                THEN LYEAR.2
                                ELSE CYEAR.2
                                END,
                    CASE    WHEN DATEPART(MM, GETDATE()) > 3
                                THEN LYEAR.3
                                ELSE CYEAR.3
                                END,
                    CASE    WHEN DATEPART(MM, GETDATE()) > 4
                                THEN LYEAR.4
                                ELSE CYEAR.4
                                END
                    --Add rest of CASE statements for remaining months
            FROM    LYEAR AS L
                    JOIN CYEAR AS C
                    ON  L.SKU = C.SKU
                    AND L.Title = C.Title

Другие вопросы по теме