sql - 想要透视表。并生成动态 SQL 字符串并执行

标签 sql sql-server sql-server-2008 sql-server-2012

创建表脚本

CREATE TABLE #TableA
(
     A           VARCHAR(50),
     Allocations INT,
     Seats       INT,
     EndDate     DATETIME
);

插入表格脚本

INSERT INTO #TableA
VALUES     ('ABC',450,23,'2017-10-05'),
           ('ABC',23,765,'2017-05-01'),
           ('PQR',54,34,'2017-07-04'),
           ('ABC',234,45,'2017-11-27'),
           ('PQR',987,76,'2017-03-05'),
           ('ABC',76,65,'2017-02-23'),
           ('PQR',89,324,'2017-08-14'),
           ('ABC',45,34,'2017-07-13'); 

#TableA 的输出

A    |  Allocations  |  Seats  |    EndDate                  |
-----+---------------+---------+-----------------------------+
ABC  |  450          |   23    |    2017-10-05 00:00:00.000  |
ABC  |   23          |  765    |    2017-05-01 00:00:00.000  |
PQR  |   54          |   34    |    2017-07-04 00:00:00.000  |
ABC  |  234          |   45    |    2017-11-27 00:00:00.000  |
PQR  |  987          |   76    |    2017-03-05 00:00:00.000  |
ABC  |   76          |   65    |    2017-02-23 00:00:00.000  |
PQR  |   89          |  324    |    2017-08-14 00:00:00.000  |
ABC  |   45          |   34    |    2017-07-13 00:00:00.000  |

我希望以下查询是动态的:

WITH T AS 
(
    SELECT 
        A, thing, priority, value, d
    FROM   
        #TableA
    CROSS APPLY (VALUES(CAST(EndDate AS DATE)))D(d)
    CROSS APPLY (VALUES(1, 'A', NULL),
                       (2, 'Allocations', Allocations),
                       (3, 'Seats', Seats)) V(priority, thing, value)
)
SELECT 
    thing, 
    case when thing = 'A' THEN A ELSE CAST(ISNULL([2017-02-23],0) AS VARCHAR(50)) END AS [2017-02-23],
    case when thing = 'A' THEN A ELSE CAST(ISNULL([2017-03-05],0) AS VARCHAR(50)) END AS [2017-03-05],
    case when thing = 'A' THEN A ELSE CAST(ISNULL([2017-05-01],0) AS VARCHAR(50)) END AS [2017-05-01],
    case when thing = 'A' THEN A ELSE CAST(ISNULL([2017-07-04],0) AS VARCHAR(50)) END AS [2017-07-04],
    case when thing = 'A' THEN A ELSE CAST(ISNULL([2017-07-13],0) AS  VARCHAR(50)) END AS [2017-07-13],
    case when thing = 'A' THEN A ELSE CAST(ISNULL([2017-08-14],0) AS VARCHAR(50)) END AS [2017-08-14],
    case when thing = 'A' THEN A ELSE CAST(ISNULL([2017-10-05],0) AS VARCHAR(50)) END AS [2017-10-05],
    case when thing = 'A' THEN A ELSE CAST(ISNULL([2017-11-27],0) AS VARCHAR(50)) END AS [2017-11-27]
FROM 
    T
PIVOT 
    (SUM(value) FOR d in (
                            [2017-02-23],
                            [2017-03-05],
                            [2017-05-01],
                            [2017-07-04],
                            [2017-07-13],
                            [2017-08-14],
                            [2017-10-05],
                            [2017-11-27])) P
ORDER BY A, priority;

这里我想要动态字符串生成 EndDate 列并执行该查询并且必须给出输出。

最佳答案

你可以使用这个脚本。

DECLARE @ColumnNamesSelect NVARCHAR(MAX) =''
SELECT  @ColumnNamesSelect = @ColumnNamesSelect + ', case when thing = ''A'' THEN A ELSE CAST(ISNULL(' + QUOTENAME ( ColName ) + ',0) AS VARCHAR(50)) END AS ' + QUOTENAME ( ColName  )  
FROM (SELECT DISTINCT CONVERT(VARCHAR(10),EndDate,120) ColName FROM #TableA ) AS T
SET @ColumnNamesSelect = STUFF(@ColumnNamesSelect,1,1,'')

DECLARE @ColumnNamesWhere NVARCHAR(MAX) =''
SELECT  @ColumnNamesWhere = @ColumnNamesWhere + ', ' + QUOTENAME ( ColName )   
FROM (SELECT DISTINCT CONVERT(VARCHAR(10),EndDate,120) ColName FROM #TableA ) AS T
SET @ColumnNamesWhere = STUFF(@ColumnNamesWhere,1,1,'')


DECLARE @SqlText NVARCHAR(MAX) =
'WITH T
     AS (SELECT A,
                thing,
                priority,
                value,
                d
         FROM   #TableA
                CROSS APPLY (VALUES(CAST(EndDate AS DATE)))D(d)
                CROSS APPLY (VALUES(1, ''A'', NULL),
                                   (2, ''Allocations'', Allocations),
                                   (3, ''Seats'', Seats)) V(priority, thing, value))
SELECT thing, ' + @ColumnNamesSelect +
' FROM T
      PIVOT (SUM(value) FOR d IN (' + @ColumnNamesWhere + ') ) P'
+' ORDER BY A, priority;'
EXEC sp_executesql @SqlText

print @SqlText

DROP TABLE #TableA

结果:

thing       2017-02-23                                         2017-03-05                                         2017-05-01                                         2017-07-04                                         2017-07-13                                         2017-08-14                                         2017-10-05                                         2017-11-27
----------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- --------------------------------------------------
A           ABC                                                ABC                                                ABC                                                ABC                                                ABC                                                ABC                                                ABC                                                ABC
Allocations 76                                                 0                                                  23                                                 0                                                  45                                                 0                                                  450                                                234
Seats       65                                                 0                                                  765                                                0                                                  34                                                 0                                                  23                                                 45
A           PQR                                                PQR                                                PQR                                                PQR                                                PQR                                                PQR                                                PQR                                                PQR
Allocations 0                                                  987                                                0                                                  54                                                 0                                                  89                                                 0                                                  0
Seats       0                                                  76                                                 0                                                  34                                                 0                                                  324                                                0                                                  0

关于sql - 想要透视表。并生成动态 SQL 字符串并执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46783843/

相关文章:

sql - 从表列名称和数据创建 json 键值

时间:2019-03-17 标签:c#SQLCOMMAND给出错误

sql-server-2008 - SQL 服务器 : Many to Many

mysql - 选择在 where 中过滤的 JSON 部分

python - 我如何从 SELECT 查询中获取最大值或最小值

C# 提高 SQLite SELECT 性能

sql - 我可以限制 SQL 用户只能使用存储过程吗?

SQL - 根据约束只接受大写字母

sql - 如何为多语言列创建全文索引?

sql - HQL意外 token “(”子查询选择