2017-07-30 111 views
1

我有2個表:轉換多個行到一個SQL Server中

產品

ProductId | Name | Description 
----------+-------+------------------------------------- 
1   | shirt | this is description for shirt 
2   | pent | this is description for pent 

ProductOverride

ProductOverrideId | ColumnId | Value     | ProductId 
------------------+-----------+------------------------+----------- 
1     | 1   | overridden name  | 1 
2     | 2   | overridden description | 1 

其中ColumnIdsys.columnscolumn_id

我要選擇具有下列要求的所有產品:

如果產品名稱或產品說明中ProductOverride表被覆蓋,得到的名稱/描述重寫的值,否則得到的名稱/描述值產品表。

輸出示例:

ProductId | Name   | Description 
----------+-----------------+--------------------------- 
1   | overridden name | overridden description 
2   | pent   | this is description for pent 

我有以下查詢返回確切的結果。

DECLARE @productNameColumnId INT = 1; 
DECLARE @productDescriptionColumnId INT = 2; 

WITH OverriddenProductNameCTE ([Value], [ProductId]) AS 
(
    SELECT 
     temp.[Value], temp.ProductId 
    FROM 
     ProductOverride temp 
    WHERE 
     temp.ColumnId = @productNameColumnId 
), OverriddenProductDescriptionCTE ([Value], [ProductId]) AS 
(
    SELECT 
     temp.[Value], temp.ProductId 
    FROM 
     ProductOverride temp 
    WHERE 
     temp.ColumnId = @productDescriptionColumnId 
) 
SELECT 
    p.ProductId, 
    CASE 
     WHEN EXISTS(SELECT [Value] 
        FROM OverriddenProductNameCTE opnc 
        WHERE opnc.ProductId = p.ProductId) 
      THEN (SELECT [Value] 
       FROM OverriddenProductNameCTE opnc 
       WHERE opnc.ProductId = p.ProductId) 
      ELSE p.[Name] 
    END AS [Name], 
    CASE 
     WHEN EXISTS(SELECT [Value] 
        FROM OverriddenProductDescriptionCTE opdc 
        WHERE opdc.ProductId = p.ProductId) 
      THEN (SELECT [Value] 
       FROM OverriddenProductDescriptionCTE opdc 
       WHERE opdc.ProductId = p.ProductId) 
      ELSE p.[Description] 
    END AS [Description] 
FROM 
    product p 

但在CASE發言,我有以下的重複代碼:

SELECT [Value] 
FROM OverriddenProductNameCTE opnc 
WHERE opnc.ProductId = p.ProductId 

如果CASE語句的第一個條件是真實的數據庫管理系統將在THEN部分再次執行相同的查詢,這意味着。

我想在簡化查詢和處理方面都改進這個查詢。

此外,如果在這種情況下使用CTE有什麼優勢?

+0

難道只有2列,或者是隻爲例子嗎? –

+0

還有更多列。我剛剛加了2個例子。 –

回答

0

如果只有2列,我認爲你可以做最簡單的事情就是留下COALESCE參加兩次:

SELECT p.ProductId 
     ,COALESCE(poN.Value, p.Name) As Name 
     ,COALESCE(poD.Value, p.Description) As Description 
FROM Product p 
LEFT JOIN ProductOverride poN ON p.ProductId = poN.ProductId AND poN.ColumnId = 1 
LEFT JOIN ProductOverride poD ON p.ProductId = poD.ProductId AND poD.ColumnId = 2 

如果是多個列,我建議樞轉ProductOverride表和左加入到 - 像這(一個完整的例子):

創建和填充示例表(保存我們這一步在你未來的問題)

CREATE TABLE Product 
(
    ProductId int, 
    Name varchar(100), 
    Description varchar(100), 
    price int null 
); 

INSERT INTO Product VALUES 
(1, 'shirt', 'Description for shirts', 1), 
(2, 'Pants', 'Description for pants', 4), 
(3, 'Socks', 'Description for socks', 5) 

CREATE TABLE ProductOverride 
(
    ProductOverrideId int, 
    ColumnId int, 
    Value varchar(100), 
    ProductId int 
); 

INSERT INTO ProductOverride VALUES 
(1,1,'product 1 name',1), 
(2,2,'product 1 desc',1), 
(3,3,'7',1), 
(4,1,'pants name',2), 
--Note: no pants description in the override tabl 
(6,3,'8',2); 
-- Note: no socks at all in override table 

查詢:

SELECT p.ProductId 
     ,COALESCE(override.[1], p.Name) As Name 
     ,COALESCE(override.[2], p.Description) As Description 
     ,COALESCE(CAST(override.[3] as int), p.Price) As Price 
FROM Product p 
LEFT JOIN 
(
    SELECT * 
    FROM 
    (
     SELECT ProductId, Value, ColumnId -- Columns To use for pivot 
     FROM ProductOverride         
    ) ColumnsToPivot 
    PIVOT (
     max (Value) 
     for ColumnId in ([1], [2], [3]) -- Values in ColumnId column to make the column names 
    ) as pivotedData 
) as override ON p.ProductId = override.ProductId 

結果:

ProductId Name Description Price 
1 product 1 name product 1 desc 7 
2 pants name Description for pants 8 
3 Socks Description for socks 5 

You can see a live demo on rextester.

+0

你可以添加數據透視碼給你的答案嗎? –

+0

看到我編輯的答案。 –

+0

你的PIVOT代碼不起作用。我試圖運行它與2列,它給這個錯誤:'pivotedData'附近的語法不正確。 –