2015-02-28 4 views
1

Я боролся с запросом сервера MSSQL за последние 4 дня. Что бы я ни пытался, я потерпел неудачу. Если это возможно, я могу получить здесь руку.Несколько в Dynamic Pivot

Это отчет я хочу взять из запроса:

  Playstation Laptop Phone Macbook Total 
------------------------------------------------------------- 
England 1x 257$  0x 0$  0x 0$  0x 0$ 1x 257$ 
Sweden  0x 0$   1x 433$ 1x 424$ 0x 0$ 2x 857$ 
Russia  2x 472$  0x 0$  0x 0$  0x 0$ 2x 472$ 
Italy  0x 0$   0x 0$  0x 0$  0x 0$ 0x 0$ 
Total  3x 729$  1x 433$ 1x 424$ 0x 0$ 5x 1586$ 

Это мои таблицы:

Country стол:

Id Name 
---------------------------------------- 
1  England 
2  Sweden 
3  Russia 
4  Italy 

Items стол:

Id Name 
---------------------------------------- 
1  Laptop 
2  Phone 
3  Playstation 
4  Macbook 

Pre-Request стол:

Id countryId ItemId  blablabla 
---------------------------------------- 
1  1   3   blablabla 
2  2   1   blablabla 
3  2   2   blablabla 
4  3   3   blablabla 
5  3   3   blablabla 
6  2   3   blablabla 

Offers стол:

Id Price   Blablabla 
---------------------------------------- 
18  257$   Blablabla 
19  151$   Blablabla 
20  424$   Blablabla 
21  433$   Blablabla 
22  321$   Blablabla 

Request стол:

Id  preReqId  requestStatus  winOfferId 
--------------------------------------------- 
44  1   3     18 
11  2   4     21 
53  3   4     20 
87  4   3     22 
43  5   3     19 
45  6   2     Null 

блаблабла столбцы и строки не имеет значения. Только поймите с запросом таблицы отчетов, я должен использовать requestStatus > 2, чтобы получить законный отчет, и даже нет заказа из «Италии» или заказать «Macbook» они будут в любом случае. Спасибо

+0

Из какой таблицы следует выбрать название страны? –

+0

Все страны из таблицы «страна», даже если они имеют нуль, например, Id-4, в Италии нет ни одного запроса или что-либо, что он придет для отчета в любом случае, с 0x 0 $ для всех строк – TeknobilSoft

+0

Страна с 'Id = 2' (Швеция) связанные с 'ItemId = 3' (playstation). Почему соответствующая цена равна 0 на выходе? –

ответ

2

Я вставляю во временную таблицу, чтобы сделать запрос более удобочитаемым. Я написал логику внутри.

;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 
  • Click here для просмотра результат
+0

Вы настоящий спасатель жизни. Seriosly очень хорошая работа .. Спасибо, сэр! – TeknobilSoft

+0

Добро пожаловать :) @TeknoBilSoft –

+0

umm еще одна вещь tho; SELECT cols = COALESCE (cols + ', [' + ITEMNAME + ']', '[' + ITEMNAME + ']') FROM (SELECT DISTINCT ITEMNAME FROM #NEWTABLE WHERE ITEMNAME <> 'TOTAL') PV ORDER BY ITEMNAME, я могу заказать «I.Id» вместо буквенного «ITEMNAME» – TeknobilSoft