【问题标题】:Converting Rows value as Column name dynamically and finding total quantity – PIVOT动态将 Rows 值转换为列名并查找总量 - PIVOT
【发布时间】:2017-06-04 05:25:31
【问题描述】:

我有 3 张桌子 A、B、C。喜欢

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

提前致谢

【问题讨论】:

  • 我已经删除了 MySQL 标签,因为您似乎在使用 SQL Server。
  • 我是枢轴的初学者,但如果我理解正确,您希望在查询中指定 C_date 列值(在此case 5 values),因为这意味着除非您更新它,否则查询将不会适应新值(*例如 31-05-2017),对吗?但是,他的文章不是已经通过@PivotColumns 覆盖了吗? TBH 我几乎没有略读它,但这就是我的感觉。
  • c_date 是一个日期时间字段,但我只想要日期。即 05-03-2017...

标签: sql sql-server pivot


【解决方案1】:

这应该可以工作

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

【讨论】:

  • @Shalu,请澄清一下,我看到的与您的图片的唯一区别是:(1) 使用 NULL 而不是空白,(2) 缺少最后一列 [结果],它汇总了所有日期, (3) [2017-01-01] 列不包含文本(Cdate)。这些是你关心的吗?还是别的什么?
【解决方案2】:

相对于 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 

【讨论】:

  • 显示错误“关键字'DECLARE'附近的语法不正确。”
  • 太奇怪了,我已经测试过了,它可以工作。你能检查一下你的数据库中是否已经创建了表 A、B 和 C 以及视图 R_sum 吗?
  • @Shalu,我可以通过运行从CREATE VIEW 到最后的所有代码来导致该错误,也许是这样?正确的用法是直到GROUP BY,然后运行其余的。在任何情况下,它都会提供与 JonWay 相同的输出。
  • 系统要求单独执行“CREATE view”命令,所以我在“CREATE view”上方添加了注释说明。
  • 效果很好。你能帮我根据 A_name 按结果分组
猜你喜欢
  • 2012-08-17
  • 1970-01-01
  • 2018-10-03
  • 1970-01-01
  • 1970-01-01
  • 2013-05-30
  • 1970-01-01
  • 2013-08-07
  • 1970-01-01
相关资源
最近更新 更多