2015-01-30 11 views
5

In SQL Server 2008 habe ich eine Tabelle (tblStock) mit 3 Spalten:Zeilen- und Spaltensumme in dynamischer Dreh

  • PartCode (NVARCHAR (50))
  • StockQty (INT)
  • Location (NVARCHAR(50))

einige Beispieldaten unter:

PartCode StockQty Location 
    ......... ......... ......... 
    A    10  WHs-A 
    B    22  WHs-A 
    A    1  WHs-B 
    C    20  WHs-A 
    D    39  WHs-F 
    E    3  WHs-D 
    F    7  WHs-A 
    A    9  WHs-C 
    D    2  WHs-A 
    F    54  WHs-E 

Wie Verfahren zu schaffen, um das Ergebnis wie folgt bekommen?

PartCode WHs-A WHs-B WHs-C WHs-D WHs-E WHs-F Total 
........ ..... ..... ..... ...... ..... ..... ..... 
A   10  1  9  0  0  0  20 
B   22  0  0  0  0  0  22 
C   20  0  0  0  0  0  20 
D    2  0  0  0  0  39  41 
E    0  0  0  3  0  0  3 
F    7  0  0  0  54  0  61 
Total  61  1  9  3  54  39  167 

Ihre Hilfe wird sehr geschätzt, danke.

Antwort

9

SAMPLE TABLE

SELECT * INTO #tblStock 
FROM 
(
SELECT 'A' PartCode, 10 StockQty, 'WHs-A' Location 
UNION ALL 
SELECT 'B', 22, 'WHs-A' 
UNION ALL 
SELECT 'A', 1, 'WHs-B' 
UNION ALL 
SELECT 'C', 20, 'WHs-A' 
UNION ALL 
SELECT 'D', 39, 'WHs-F' 
UNION ALL 
SELECT 'E', 3, 'WHs-D' 
UNION ALL 
SELECT 'F', 7, 'WHs-A' 
UNION ALL 
SELECT 'A', 9, 'WHs-C' 
UNION ALL 
SELECT 'D', 2, 'WHs-A' 
UNION ALL 
SELECT 'F', 54, 'WHs-E' 
)TAB 

die Spalten für dynamischen Schwenk Erhalten und ersetzen NULL mit zero

DECLARE @cols NVARCHAR (MAX) 

SELECT @cols = COALESCE (@cols + ',[' + Location + ']', '[' + Location + ']') 
       FROM (SELECT DISTINCT Location FROM #tblStock) PV 
       ORDER BY Location 
-- Since we need Total in last column, we append it at last 
SELECT @cols += ',[Total]' 


--Varible to replace NULL with zero 
DECLARE @NulltoZeroCols NVARCHAR (MAX) 

SELECT @NullToZeroCols = SUBSTRING((SELECT ',ISNULL(['+Location+'],0) AS ['+Location+']' 
FROM (SELECT DISTINCT Location FROM #tblStock)TAB 
ORDER BY Location FOR XML PATH('')),2,8000) 

SELECT @NullToZeroCols += ',ISNULL([Total],0) AS [Total]' 

Sie CUBE verwenden können, um Zeilen- und Spaltensumme zu Suchen und Ersetzen NULL mit Total für die Zeilen generiert von CUBE.

DECLARE @query NVARCHAR(MAX) 
SET @query = 'SELECT PartCode,' + @NulltoZeroCols + ' FROM 
      (
       SELECT 
       ISNULL(CAST(PartCode AS VARCHAR(30)),''Total'')PartCode, 
       SUM(StockQty)StockQty , 
       ISNULL(Location,''Total'')Location    
       FROM #tblStock 
       GROUP BY Location,PartCode 
       WITH CUBE 
      ) x 
      PIVOT 
      (
       MIN(StockQty) 
       FOR Location IN (' + @cols + ') 
      ) p 
      ORDER BY CASE WHEN (PartCode=''Total'') THEN 1 ELSE 0 END,PartCode' 

EXEC SP_EXECUTESQL @query 

RESULT

enter image description here

HINWEIS führen: Wenn Sie möchten NULL statt zero als Werte verwenden @cols statt @NulltoZeroCols in dynamischen Dreh Code

EDIT:

1. Nur Gesamt-Zeile

  • den Code nicht SELECT @cols += ',[Total]' und SELECT @NullToZeroCols += ',ISNULL([Total],0) AS [Total]' anwenden.
  • Verwenden Sie ROLLUP anstelle von CUBE.

enter image description here

2. Nur Spaltensumme

  • Verwenden Sie den Code SELECT @cols += ',[Total]' und SELECT @NullToZeroCols += ',ISNULL([Total],0) AS [Total]'.
  • Verwenden Sie ROLLUP anstelle von CUBE.
  • Ändern GROUP BY Location,PartCode zu GROUP BY PartCode,Location.
  • Verwenden Sie anstelle von ORDER BY CASE WHEN (PartCode=''Total'') THEN 1 ELSE 0 END,PartCodeWHERE PartCode<>''TOTAL'' ORDER BY PartCode.

enter image description here

UPDATE: PartName für OP bringen

ich die unten Abfrage bin Aktualisierung Ergebnis hinzufügen PartName mit. Da PartName zusätzliche Ergebnisse mit CUBE hinzufügen und Verwechslungen in AND oder OR Bedingungen vermeiden, ist es besser, das geschwenkte Ergebnis mit den DISTINCT Werten in Ihrer Quellentabelle zu verknüpfen.

DECLARE @query NVARCHAR(MAX) 
SET @query = 'SELECT P.PartCode,T.PartName,' + @NulltoZeroCols + ' FROM 
      (    
       SELECT 
       ISNULL(CAST(PartCode AS VARCHAR(30)),''Total'')PartCode, 
       SUM(StockQty)StockQty , 
       ISNULL(Location,''Total'')Location    
       FROM #tblStock 
       GROUP BY Location,PartCode 
       WITH CUBE     
      ) x 
      PIVOT 
      (
       MIN(StockQty) 
       FOR Location IN (' + @cols + ') 
      ) p 
      LEFT JOIN 
      ( 
       SELECT DISTINCT PartCode,PartName 
       FROM #tblStock 
      )T 
      ON P.PartCode=T.PartCode 
      ORDER BY CASE WHEN (P.PartCode=''Total'') THEN 1 ELSE 0 END,P.PartCode' 

EXEC SP_EXECUTESQL @query 

enter image description here

+0

Ich habe aktualisiert @Sokea –

+0

Genau was ich brauche, danke @Sarath Avanavu für Ihre Lösung und Erklärung. – Sokea

+0

Willkommen :) @Sokea –

1

Sie benötigen case based aggregation zu verwenden, um die Daten zu schwenken

Um die total Reihe union

Im Fall benutzen die Location Werte werden nicht im Voraus bekannt ist, benötigen Sie einen dynamic query

Sie konstruieren Sie können auch das Schlüsselwort pivot verwenden, um dasselbe zu tun.

select partCode, 
sum(case when Location='WHs-A' then StockQty 
     else 0 end 
    ) as 'Whs-A', 
sum(case when Location='WHs-B' then StockQty 
     else 0 end 
    ) as 'Whs-B', 
sum(StockQty) as 'Total' 
from tblStock 
group by partCode 
union all 
select 'Total' as 'partCode', 
sum(case when Location='WHs-A' then StockQty 
    else 0 end) as 'Whs-A', 
sum(case when Location='WHs-B' then StockQty 
    else 0 end) as 'Whs-B', 
sum(StockQty) as 'Total' 
from tblStock 
+1

dank Radar zur Folge haben. Wie auch immer, die Position ist unbekannt Spalte, könnten Sie bitte. dynamische Abfrage bereitstellen? – Sokea