将行值转换为列名称动态并查找总数量 - PIVOT

时间:2017-05-31 08:04:45

标签: sql sql-server pivot

我有3张桌子A,B,C。比如this

需要在结合这3个表(RESULT)的sql表上显示一些细节。 我需要动态地将日期字段的值显示为列标题。 提到此链接http://www.databasejournal.com/features/mssql/converting-rows-to-columns-pivot-and-columns-to-rows-unpivot-in-sql-server.html但它是静态值。有没有办法为动态数据实现这一点。

提前致谢

2 个答案:

答案 0 :(得分:0)

这应该工作

CREATE TABLE #A (A_ID INT, A_Name Varchar(100))
INSERT INTO #A VALUES (1,'X'),(2,'Y'),(3,'Z');

CREATE TABLE  #B (B_ID INT,A_ID INT, B_Name Varchar(100))
INSERT INTO #B VALUES (10,1,'P'),(11,2,'Q'),(12,1,'R');

CREATE TABLE #C  (B_ID INT,C_DATE DATE, C_QTY INT)
INSERT INTO #C VALUES (10,'2017-01-01',100),(10,'2017-01-02',200),
                       (11,'2017-01-03',250),(11,'2017-01-03',50),(12,'2017-01-07',300);
 ------------- PIVOT AS FOLLOWS                      

DECLARE @Cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX)
SET @Cols = STUFF((SELECT distinct ',' + QUOTENAME(C_DATE) FROM #C 
    FOR XML PATH(''), TYPE   ).value('.', 'NVARCHAR(MAX)') ,1,1,'')    

SET @query =  'SELECT* FROM(
                SELECT  
                A.A_Name,
                B.B_Name,
                C.C_DATE,
                C.C_QTY
          FROM #A A
          RIGHT JOIN #B B ON A.A_ID=B.A_ID
          RIGHT JOIN #C C ON B.B_ID=C.B_ID
               ) ABC
PIVOT 
(
SUM(C_QTY) FOR [C_DATE] IN (' + @Cols + ')

) AS PV1';

EXEC sp_executesql @query 

DROP TABLE #A; DROP TABLE #B;DROP TABLE #C

答案 1 :(得分:0)

与JonWay先前提供的解决方案相关,为了添加一个'结果'使用A_name和B_name的总数量的列,我们可以创建总计视图并以这种方式将其添加到主查询中

CREATE TABLE A (A_ID INT, A_Name Varchar(100))
INSERT INTO A VALUES (1,'X'),(2,'Y'),(3,'Z');

CREATE TABLE  B (B_ID INT,A_ID INT, B_Name Varchar(100))
INSERT INTO B VALUES (10,1,'P'),(11,2,'Q'),(12,1,'R');

CREATE TABLE C  (B_ID INT,C_DATE DATE, C_QTY INT)
INSERT INTO C VALUES (10,'2017-01-01',100),(10,'2017-01-02',200),
                   (11,'2017-01-03',250),(11,'2017-01-03',50),(12,'2017-01-07',300);

-- Create the view separately after having created the tables
CREATE VIEW R_sum
AS
SELECT A.A_id, B.B_id, SUM(C.C_qty) AS Sum_qty
FROM     A INNER JOIN
                  B ON A.A_id = B.A_id INNER JOIN
                  C ON B.B_id = C.B_id
GROUP BY A.A_id, B.B_id

 ------------- PIVOT AS FOLLOWS                      

DECLARE @Cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX)
SET @Cols = STUFF((SELECT distinct ',' + QUOTENAME(C_DATE) FROM C 
    FOR XML PATH(''), TYPE   ).value('.', 'NVARCHAR(MAX)') ,1,1,'')    

SET @query =  'SELECT * FROM(
                SELECT  
                A.A_Name,
                B.B_Name,
                C.C_DATE,
                C.C_QTY,
                R.Sum_qty as Result
          FROM A A
          INNER JOIN B ON A.A_ID=B.A_ID
          RIGHT JOIN C ON B.B_ID=C.B_ID
          RIGHT JOIN R_Sum R ON B.A_ID=R.A_ID AND B.B_ID=R.B_ID
               ) ABC
PIVOT 
(
SUM(C_QTY) FOR [C_DATE] IN (' + @Cols + ')

) AS PV1';

EXEC sp_executesql @query