Pivot and Unpivot for 4 joined table SQL Server

核能气质少年 提交于 2019-12-12 03:53:49

问题


I'm using SQL Server 2012, and I want to create a pivot table with 4 joined tables.

Here's my query :

SELECT 
    a.Itemno, a.Qty as PlanMilling, 
    ISNULL(b.MinimStock, 0) as MinStock, 
    CAST(a.ScheduleDate as Date) AS Schedule, 
    ISNULL(SUM(c.Qty), 0) as QtyBuilding,
    ISNULL(d.RunQty, 0) as QtyStock, 
    d.itemcode, 
    ISNULL((a.Qty + d.RunQty) - SUM(c.Qty), 0) as Balance
FROM 
    Schedule a 
LEFT OUTER JOIN 
    Item b ON a.ItemNo = b.ItemNo
LEFT OUTER JOIN 
    ShopOrderList c on a.ItemNo = c.ItemNo and a.ScheduleDate = c.ScheduleDate
LEFT OUTER JOIN  
    (SELECT  
         RunQty, ItemCode  
     FROM
         ICMutTran a
     INNER JOIN
         (SELECT 
              itemcode as ItemNo, max(id) as maxid 
          FROM
              ICMutTran 
          GROUP BY 
              itemcode) AS b ON a.id = b.maxid) d ON (a.ItemNo = d.ItemCode)
GROUP BY 
    a.ItemNo, a.Qty, b.MinimStock, a.ScheduleDate, d.RunQty, d.itemcode

and the result :

ItemNo   |   PlanMilling   |   MinStock   |   Schedule   |   QtyBuilding   |   QtyStock   |   ItemCode   |
----------------------------------------------------------------------------------------------------------
123      |   1000          | 100          | 2016-02-04   | 200             | 1500         | 123          |
123      |   2000          | 100          | 2016-02-05   | 100             | 1500         | 123          |
123      |   1500          | 100          | 2016-02-06   | 150             | 1500         | 123          |

What I need is this:

ColName     |   2016-02-04   |   2016-02-05   |   2016-02-06   |
----------------------------------------------------------------
PlanMilling |   1000         |   2000         |   1500         |
MinStock    |    100         |    100         |    100         |
QtyBuilding |    200         |    100         |    150         |
QtyStock    |   1500         |   1500         |   1500         |

Can anyone solve my case? I really need your help (sorry for my bad english)..

Thanks


回答1:


This does your PIVOT dynamically on ScheduleDate. You can use this script by rewriting your SELECT statement as

SELECT <your selects> INTO #tt FROM <the rest of your query>

and use the part of the script after the CREATE TABLE #tt and INSERT INTO #tt statements. After pivotting don't forget to DROP the temporary table.

CREATE TABLE #tt(ItemNo INT,PlanMilling INT,MinStock INT,Schedule VARCHAR(10),QtyBuilding INT,QtyStock INT,ItemCode INT);
INSERT INTO #tt(ItemNo,PlanMilling,MinStock,Schedule,QtyBuilding,QtyStock,ItemCode)VALUES
    (123,1000,100,'2016-02-04',200,1500,123),
    (123,2000,100,'2016-02-05',100,1500,123),
    (123,1500,100,'2016-02-06',150,1500,123);

DECLARE @schedule_dates NVARCHAR(MAX)=STUFF((
    SELECT DISTINCT
        ','+QUOTENAME(Schedule)
    FROM
        #tt
    FOR
        XML PATH('')
    ),1,1,''
);

DECLARE @stmt NVARCHAR(MAX)=N'
    SELECT
        ColName,' +
        @schedule_dates+'
    FROM
        #tt
        UNPIVOT (
            value 
            FOR ColName in (PlanMilling,MinStock,QtyBuilding,QtyStock)
        ) AS up
        PIVOT (
            MAX(value) 
            FOR Schedule IN ('+@schedule_dates+')
        ) AS p;
';
EXECUTE sp_executesql @stmt;

DROP TABLE #tt;

Results:

+-------------+------------+------------+------------+
|   ColName   | 2016-02-04 | 2016-02-05 | 2016-02-06 |
+-------------+------------+------------+------------+
| MinStock    |        100 |        100 |        100 |
| PlanMilling |       1000 |       2000 |       1500 |
| QtyBuilding |        200 |        100 |        150 |
| QtyStock    |       1500 |       1500 |       1500 |
+-------------+------------+------------+------------+



回答2:


Here's one option using union all with conditional aggregation (although it's a little ugly):

with cte as (
    <<your query here>>
)
select 'PlanMilling' ColName,
       max(case when Schedule = '2016-02-04' then PlanMilling end) '2016-02-04',
       max(case when Schedule = '2016-02-05' then PlanMilling end) '2016-02-05',
       max(case when Schedule = '2016-02-06' then PlanMilling end) '2016-02-06'
from cte
union all
select 'MinStock' ColName,
       max(case when Schedule = '2016-02-04' then MinStock end) '2016-02-04',
       max(case when Schedule = '2016-02-05' then MinStock end) '2016-02-05',
       max(case when Schedule = '2016-02-06' then MinStock end) '2016-02-06'
from cte
union all
select 'QtyBuilding' ColName,
       max(case when Schedule = '2016-02-04' then QtyBuilding end) '2016-02-04',
       max(case when Schedule = '2016-02-05' then QtyBuilding end) '2016-02-05',
       max(case when Schedule = '2016-02-06' then QtyBuilding end) '2016-02-06'
from cte
union all
select 'QtyStock' ColName,
       max(case when Schedule = '2016-02-04' then QtyStock end) '2016-02-04',
       max(case when Schedule = '2016-02-05' then QtyStock end) '2016-02-05',
       max(case when Schedule = '2016-02-06' then QtyStock end) '2016-02-06'
from cte


来源:https://stackoverflow.com/questions/35192602/pivot-and-unpivot-for-4-joined-table-sql-server

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!