BẢNG MẪU
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
Lấy các cột để xoay vòng động và thay thế NULL
với 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]'
Bạn có thể sử dụng CUBE
để tìm tổng số hàng và cột và thay thế NULL
với Total
cho các hàng được tạo từ 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
- Nhấp vào đây để xem kết quả
KẾT QUẢ
LƯU Ý:Nếu bạn muốn NULL
thay vì zero
dưới dạng giá trị, hãy sử dụng @cols
thay vì @NulltoZeroCols
trong mã tổng hợp động
CHỈNH SỬA:
1. Chỉ hiển thị Tổng số hàng
- Không sử dụng mã
SELECT @cols += ',[Total]'
vàSELECT @NullToZeroCols += ',ISNULL([Total],0) AS [Total]'
. - Sử dụng
ROLLUP
thay vìCUBE
.
2. Chỉ hiển thị Tổng số cột
- Sử dụng mã
SELECT @cols += ',[Total]'
vàSELECT @NullToZeroCols += ',ISNULL([Total],0) AS [Total]'
. - Sử dụng
ROLLUP
thay vìCUBE
. - Thay đổi
GROUP BY Location,PartCode
đếnGROUP BY PartCode,Location
. - Thay vì
ORDER BY CASE WHEN (PartCode=''Total'') THEN 1 ELSE 0 END,PartCode
, sử dụngWHERE PartCode<>''TOTAL'' ORDER BY PartCode
.
CẬP NHẬT:Để mang theo PartName
cho OP
Tôi đang cập nhật truy vấn bên dưới để thêm PartName
với kết quả. Kể từ PartName
sẽ thêm kết quả bổ sung với CUBE
và để tránh nhầm lẫn trong AND
hoặc OR
điều kiện, tốt hơn nên kết hợp kết quả xoay vòng với DISTINCT
giá trị trong bảng nguồn của bạn.
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
- Nhấp vào đây để xem kết quả