【问题标题】:Dynamic table creation in SQL Server [duplicate]SQL Server 中的动态表创建 [重复]
【发布时间】:2014-12-11 14:00:14
【问题描述】:

我有这样的情况

+---------+-----------+------------+
| FieldNo | FieldName | Substring  |
+---------+-----------+------------+
|       1 | A         | 8          |
|       1 | A         | A          |
|       1 | A         | DC         |
|       2 | B         | 7          |
|       3 | C         | 22         |
|       3 | C         | 37         |
+---------+-----------+------------+

需要这样的输出:

+----+------+------+
| A  |  B   |  C   |
+----+------+------+
| 8  | 7    | 22   |
| A  | Null | 37   |
| DC | Null | Null |
+----+------+------+

有什么建议可以在 SQL Server 中做到这一点吗?

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT ',' + QUOTENAME(Field_name) 
                    from bear_crossjoin
                    group by FIELD_NAME, FIELDNUMBER
                    order by FIELDNUMBER
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = N'SELECT ' + @cols + N' from 
             (
                select substring, Field_name
                from bear_crossjoin
            ) x
            pivot 
            (
                max(substring)
                for field_name in (' + @cols + N')
            ) p '

exec sp_executesql @query

【问题讨论】:

  • 只需搜索SQL ServerPIVOT。如果您有具体问题,请随时询问
  • 我需要在顶部的字段名 A、B、C。上面的示例将其作为行而不是列。
  • 你检查过任何关于 PIVOT 的类似问题吗?你对他们有意见吗?
  • @Arun.K 您可以使用row_number() 技巧以及我的答案here,其中包括一个动态解决方案。基本上,您需要创建一个 sql 字符串,该字符串将执行并为您提供最终结果。
  • @Arun.K - 代码只需稍作改动即可工作 - 请参阅此演示 - sqlfiddle.com/#!3/5396ed/5

标签: sql-server stored-procedures pivot


【解决方案1】:

我假设表名是 tblTemp。试试这个

DECLARE @colList NVARCHAR(max)
DECLARE @query NVARCHAR(max)

select @colList = coalesce(@colList + ',', '') +  convert(varchar(12),TT.FIELDNAME)
from (SELECT DISTINCT FIELDNAME FROM tblTemp) TT
order by TT.FIELDNAME


SET @query = 'SELECT ' + @colList + ' FROM
(
SELECT row_number() over(partition by FIELDNO
                        order by FIELDNO) seq,
       FieldName, [Substring]
FROM tblTemp ) als
PIVOT
( MAX([SUBSTRING])
  FOR FieldName IN (' + @colList + ')
) piv'

exec sp_executesql @query

fiddle

【讨论】:

  • 抛出错误必须声明标量变量“@results”。
  • @Arun.K 如果您不显示您正在使用的代码,任何人都无法提供帮助。你从哪里得到@results?这个答案甚至不包括那个变量。
  • 我的错,我首先使用了@results,但为了更好地理解,将其更改为 colList。编辑:VARCHAR 到 NVARCHAR,以及 AFTER 之后的空格:query = 'SELECT'
【解决方案2】:

您似乎正在尝试按行号而不是直接在字段名称上进行 PIVOT。下面的方法使用行号来获得所需的输出:

DECLARE @Data TABLE (FieldNo INT, FieldName VARCHAR(50), [Substring] VARCHAR(500))
INSERT @Data VALUES
    (1, 'A', '8'),
    (1, 'A', 'A'),
    (1, 'A', 'DC'),
    (2, 'B', '7'),
    (3, 'C', '22'),
    (3, 'C', '37')

;WITH DataRows AS (
    SELECT
        FieldName,
        [Substring],
        ROW_NUMBER() OVER (PARTITION BY FieldNo ORDER BY FieldName, [Substring]) AS RowNum
    FROM @Data
)
    SELECT
        CONVERT(VARCHAR(10), [A]) AS [A],
        CONVERT(VARCHAR(10), [B]) AS [B],
        CONVERT(VARCHAR(10), [C]) AS [C]
    FROM DataRows
        PIVOT (MAX([Substring]) FOR FieldName IN ([A], [B], [C])) T

这会产生所需的输出:

A          B          C
---------- ---------- ----------
8          7          22
A          NULL       37
DC         NULL       NULL

【讨论】:

  • Jason,我应该在这里提到什么 FOR FieldName IN ([A], [B], [C])) T 因为我有大约 978 列。
  • 你刚才说的是978 COLUMNS吗?如果是,使用动态sql。我猜这是唯一的选择
  • 是的 978 列。我需要一个动态sql,我举的例子很少。对动态 sql 有什么建议吗?
  • 查看我对动态 sql 和数据透视的回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-05
  • 1970-01-01
  • 2016-08-19
  • 1970-01-01
  • 1970-01-01
  • 2012-09-01
  • 1970-01-01
相关资源
最近更新 更多