2015-09-05 87 views
-1

我有複雜的查詢,效果很好(MS SQL 2012)。但總結相同的價格項目時會出現錯誤。它對它們進行了正確的計數,但只需要花費一次,而不是將它們作爲計數。只有當相同的商品具有相同的價格並來自同一國家時纔會出現。這是我的問題;Dynamic Pivot中總計錯誤值

CREATE TABLE #ITEMS(ID INT,NAME VARCHAR(30)) 

INSERT INTO #ITEMS 
SELECT 1,  'laptop' 
UNION ALL 
SELECT 2,  'phone' 
UNION ALL 
SELECT 3,  'playstation' 
UNION ALL 
SELECT 4,  'MacBook' 

CREATE TABLE #Country(ID INT,NAME VARCHAR(30)) 

INSERT INTO #Country 
SELECT 1,  'England' 
UNION ALL 
SELECT 2,  'Sweden' 
UNION ALL 
SELECT 3,  'Russia' 
UNION ALL 
SELECT 4,  'Italy' 


CREATE TABLE [#Pre-Request](Id INT, countryId INT, ItemId INT) 

INSERT INTO [#Pre-Request] 
SELECT 1,1,3 
UNION ALL 
SELECT 2,2,1 
UNION ALL 
SELECT 3,2,2 
UNION ALL 
SELECT 4,3,3 
UNION ALL 
SELECT 5,3,3 
UNION ALL 
SELECT 6,2,3 

CREATE TABLE #Offers(Id INT, PRICE VARCHAR(50)) 

INSERT INTO #Offers 
SELECT 18,'257$' 
UNION ALL 
SELECT 19,'151$' 
UNION ALL 
SELECT 20,'424$' 
UNION ALL 
SELECT 21,'433$' 
UNION ALL 
SELECT 22,'151$' 

CREATE TABLE #Request(Id INT, preReqId INT, requestStatus INT,winOfferId INT) 

INSERT INTO #Request 
SELECT 44,  1,   3,     18 
UNION ALL 
SELECT 11,  2,   4,     21 
UNION ALL 
SELECT 53,  3,   4,     20 
UNION ALL 
SELECT 87,  4,   3,     22 
UNION ALL 
SELECT 43,  5,   3,     19 
UNION ALL 
SELECT 43,  6,   2,     Null 




;WITH CTE AS 
(
    SELECT DISTINCT I.NAME ITEMNAME,C.NAME COUNTRYNAME 
    ,CAST(REPLACE(TAB.PRICE,'$','')AS INT)PRICE 
    ,COUNT(CASE WHEN TAB.PRICE IS NOT NULL THEN I.NAME END) OVER(PARTITION BY C.NAME,I.NAME) CNTITEM  
    FROM [#Pre-Request] PR 
    LEFT JOIN #Items I ON PR.ITEMID=I.ID 
    LEFT JOIN #COUNTRY C ON PR.COUNTRYID = C.ID 
    OUTER APPLY 
    (
     SELECT R.preReqId,R.winOfferId,O.PRICE 
     FROM #Request R 
     JOIN #Offers O ON R.winOfferId=O.Id 
     WHERE PR.ID=R.preReqId 
    )TAB 

    UNION 
    -- Used to select Item name and country that are not in Pre-request table and other tables 
    SELECT I.NAME ,C.NAME ,NULL,0 
    FROM #Items I 
    CROSS JOIN #COUNTRY C 
) 
,CTE2 AS 
(
    -- Find the sum for number of items 
    SELECT DISTINCT ISNULL(ITEMNAME,'TOTAL')ITEMNAME,ISNULL(COUNTRYNAME,'TOTAL')COUNTRYNAME, 
    SUM(PRICE)PRICE 
    FROM CTE 
    GROUP BY ITEMNAME,COUNTRYNAME 
    WITH CUBE 
) 
,CTE3 AS 
(
    -- Find the sum of PRICE 
    SELECT DISTINCT ISNULL(ITEMNAME,'TOTAL')ITEMNAME,ISNULL(COUNTRYNAME,'TOTAL')COUNTRYNAME--,CNTITEM 
    ,SUM(CNTITEM)CNTITEM  
    FROM 
    (
     SELECT DISTINCT ITEMNAME,COUNTRYNAME,CNTITEM 
     FROM CTE 
    )TAB 
    GROUP BY ITEMNAME,COUNTRYNAME 
    WITH CUBE 
) 
SELECT C2.*,C3.CNTITEM, 
CAST(C3.CNTITEM AS VARCHAR(20))+'x'+' ' + CAST(C2.PRICE AS VARCHAR(20))+'$' NEWCOL 
INTO #NEWTABLE 
FROM CTE2 C2 
JOIN CTE3 C3 ON C2.COUNTRYNAME=C3.COUNTRYNAME AND C2.ITEMNAME=C3.ITEMNAME 







DECLARE @cols NVARCHAR (MAX) 

SELECT @cols = COALESCE (@cols + ',[' + ITEMNAME + ']', '[' + ITEMNAME + ']') 
       FROM (SELECT DISTINCT ITEMNAME FROM #NEWTABLE WHERE ITEMNAME<>'TOTAL') PV 
       ORDER BY ITEMNAME 
-- Since we need Total in last column, we append it at last 
SELECT @cols += ',[Total]' 


DECLARE @query NVARCHAR(MAX) 
SET @query = 'SELECT COUNTRYNAME,' + @cols + ' FROM 
      (
       SELECT DISTINCT ITEMNAME,COUNTRYNAME,ISNULL(NEWCOL,''0x 0$'')NEWCOL 
       FROM #NEWTABLE 
      ) x 
      PIVOT 
      (
       MIN(NEWCOL) 
       FOR ITEMNAME IN (' + @cols + ') 
      ) p 
      ORDER BY CASE WHEN (COUNTRYNAME=''Total'') THEN 1 ELSE 0 END,COUNTRYNAME' 

EXEC SP_EXECUTESQL @query 

這裏是結果;

enter image description here

正如你可以看到有2個「遊戲站」,從「俄羅斯」,就需要正確的次數(2次),但只取1價「151 $」(通常它必須是302 $)。我怎樣才能解決這個問題,而不是從查詢做重大更改?謝謝。

+0

我檢查快速查詢,我認爲問題在於轉軸之前。如果對我來說違反直覺,第二個存儲在項目x總價格的一個列號中。當我看到'2x 302'時,我想象每個302 $ 2個項目,總成本302個項目不能包含2個項目,您不能將每個產品和總數的項目編號/價格總和分成兩列分開列嗎? – lad2025

+0

您正在使用哪個版本的SQL Server? – jpw

+0

@jpw MS SQL 2012 – TeknobilSoft

回答

2

我認爲這是做你想做的。問題出在你的第一個CTE上,你需要進行項目計數,並在ItemName,CountryName和Price上得到一個明確的結果。

而不是得到一個獨特的,做一個組,如下所示和SUM的價格。

SELECT I.NAME ITEMNAME, C.NAME COUNTRYNAME 
,SUM(CAST(REPLACE(TAB.PRICE,'$','')AS INT))PRICE 
,COUNT(CASE WHEN TAB.PRICE IS NOT NULL THEN 1 ELSE NULL END) CNTITEM  
FROM [#Pre-Request] PR 
LEFT JOIN #Items I ON PR.ITEMID=I.ID 
LEFT JOIN #COUNTRY C ON PR.COUNTRYID = C.ID 
OUTER APPLY 
(
    SELECT R.preReqId,R.winOfferId,O.PRICE 
    FROM #Request R 
    JOIN #Offers O ON R.winOfferId=O.Id 
    WHERE PR.ID=R.preReqId 
)TAB 
GROUP BY 
    I.NAME 
    ,C.NAME 

編輯: 這裏是我得到的結果:

enter image description here

這裏是所有的代碼從熱膨脹係數開始的:

;WITH CTE AS 
(
    SELECT I.NAME ITEMNAME, C.NAME COUNTRYNAME 
    ,SUM(CAST(REPLACE(TAB.PRICE,'$','')AS INT))PRICE 
    ,COUNT(CASE WHEN TAB.PRICE IS NOT NULL THEN 1 ELSE NULL END) CNTITEM  
    FROM [#Pre-Request] PR 
    LEFT JOIN #Items I ON PR.ITEMID=I.ID 
    LEFT JOIN #COUNTRY C ON PR.COUNTRYID = C.ID 
    OUTER APPLY 
    (
     SELECT R.preReqId,R.winOfferId,O.PRICE 
     FROM #Request R 
     JOIN #Offers O ON R.winOfferId=O.Id 
     WHERE PR.ID=R.preReqId 
    )TAB 
    GROUP BY 
     I.NAME 
     ,C.NAME 

    UNION 
    -- Used to select Item name and country that are not in Pre-request table and other tables 
    SELECT I.NAME ,C.NAME ,NULL,0 
    FROM #Items I 
    CROSS JOIN #COUNTRY C 
) 
,CTE2 AS 
(
    -- Find the sum for number of items 
    SELECT DISTINCT ISNULL(ITEMNAME,'TOTAL')ITEMNAME,ISNULL(COUNTRYNAME,'TOTAL')COUNTRYNAME, 
    SUM(PRICE)PRICE 
    FROM CTE 
    GROUP BY ITEMNAME,COUNTRYNAME 
    WITH CUBE 
) 
,CTE3 AS 
(
    -- Find the sum of PRICE 
    SELECT DISTINCT ISNULL(ITEMNAME,'TOTAL')ITEMNAME,ISNULL(COUNTRYNAME,'TOTAL')COUNTRYNAME--,CNTITEM 
    ,SUM(CNTITEM)CNTITEM  
    FROM 
    (
     SELECT DISTINCT ITEMNAME,COUNTRYNAME,CNTITEM 
     FROM CTE 
    )TAB 
    GROUP BY ITEMNAME,COUNTRYNAME 
    WITH CUBE 
) 

SELECT C2.*,C3.CNTITEM, 
CAST(C3.CNTITEM AS VARCHAR(20))+'x'+' ' + CAST(C2.PRICE AS VARCHAR(20))+'$' NEWCOL 
INTO #NEWTABLE 
FROM CTE2 C2 
JOIN CTE3 C3 ON C2.COUNTRYNAME=C3.COUNTRYNAME AND C2.ITEMNAME=C3.ITEMNAME 







DECLARE @cols NVARCHAR (MAX) 

SELECT @cols = COALESCE (@cols + ',[' + ITEMNAME + ']', '[' + ITEMNAME + ']') 
       FROM (SELECT DISTINCT ITEMNAME FROM #NEWTABLE WHERE ITEMNAME<>'TOTAL') PV 
       ORDER BY ITEMNAME 
-- Since we need Total in last column, we append it at last 
SELECT @cols += ',[Total]' 


DECLARE @query NVARCHAR(MAX) 
SET @query = 'SELECT COUNTRYNAME,' + @cols + ' FROM 
      (
       SELECT DISTINCT ITEMNAME,COUNTRYNAME,ISNULL(NEWCOL,''0x 0$'')NEWCOL 
       FROM #NEWTABLE 
      ) x 
      PIVOT 
      (
       MIN(NEWCOL) 
       FOR ITEMNAME IN (' + @cols + ') 
      ) p 
      ORDER BY CASE WHEN (COUNTRYNAME=''Total'') THEN 1 ELSE 0 END,COUNTRYNAME' 

EXEC SP_EXECUTESQL @query 
+0

現在它給「604 $」和其他值出錯了? – TeknobilSoft

+0

我添加了我得到的結果和整個代碼塊。我沒有看到$ 604在我的結果中回來。 – PeterDNCO

+0

工作很好,非常感謝你的先生! – TeknobilSoft