【问题标题】:SQL Sever Pivot Many ColumnsSQL Server 透视多列
【发布时间】:2012-03-07 04:20:39
【问题描述】:

我从未使用过 SQL Pivot,但我认为现在是我的机会。问题是,我真的不知道怎么做。我一直在阅读文档,但似乎我想要的结果可能会稍微复杂一些,此时我几乎无法处理简单的枢轴。

我有这张桌子

Create table dataTable (dataID int, containerID int)

我想查询它,以便我的结果集采用以下格式:

Create table pivotTable (DataID int, Container1 bit, Container2 bit, ...ContainerN bit)

dataTable 中的每个 DataID 都成为一行,如果元组 {DataID, ContainerN} 存在于 dataTable 中,则 ConatinerN 的位值为 1,否则为 0。 ContainerID 有 480 个,所以我宁愿不手动指定它们,但如果有必要,我可以。

感谢您的帮助!

【问题讨论】:

标签: sql-server tsql pivot


【解决方案1】:

可能是这样的:

测试数据

Create table dataTable (dataID int, containerID int)

INSERT INTO dataTable
VALUES
    (1,1),
    (2,1),
    (3,3),
    (4,2)

唯一列

DECLARE @cols VARCHAR(MAX)
DECLARE @colsWithIsNull VARCHAR(MAX)
;WITH CTE
AS
(
    SELECT
        ROW_NUMBER() OVER(PARTITION BY containerID ORDER BY containerID) AS RowNbr,
        CAST(containerID AS VARCHAR(100)) AS containerID
    FROM 
        dataTable
)
SELECT  @cols = COALESCE(@cols + ','+QUOTENAME('Container'+containerID),
                    QUOTENAME('Container'+containerID)),
        @colsWithIsNull= COALESCE(@colsWithIsNull + ',CAST(ISNULL('+QUOTENAME('Container'+containerID)+',0) AS BIT) AS '+QUOTENAME('Container'+containerID),
                    'CAST(ISNULL('+QUOTENAME('Container'+containerID)+',0) AS BIT) AS '+QUOTENAME('Container'+containerID))
FROM
    CTE
WHERE
    CTE.RowNbr=1

动态枢轴

DECLARE @query NVARCHAR(4000)=
N'SELECT
    dataID,
    '+@colsWithIsNull+'
FROM
(
    SELECT
        ''Container''+CAST(dataTable.containerID AS VARCHAR(100)) AS ContainerText,
        1 AS isContainer,
        dataTable.dataID
    FROM
        dataTable
) AS p
PIVOT
(
    MAX(isContainer)
    FOR ContainerText IN ('+@cols+')
) AS pvt'

EXECUTE(@query)

在我的情况下,我将删除测试表:

DROP TABLE dataTable

【讨论】:

  • 宾果游戏。我已经从 SSRS 中获得了我想要的数据,但这正是我想要的。谢谢。
【解决方案2】:

像这样旋转数据并没有多大意义。这是在应用程序的数据访问层中完成的更好的工作。正如你所说,你应该像这样返回数据集......

{ DataID INT, ContainerNumber INT }

为了让您的生活更轻松,请仅退回列中有1 的容器,然后填写空白处。

【讨论】:

  • 我不确定我是否遵循。我拥有的数据已经是{ DataID INT, ContainerNumber INT } 格式,但这不是我想要的。
  • 我想说的是,除非绝对必要,否则您的数据库不应返回该旋转结果集。这件作品属于应用程序的其他地方。也就是说,如果您必须这样做,请使用游标遍历所有行并动态构建透视数据的查询。
  • 其实不是,这是一个人工拼凑的临时数据集。话虽如此,存储一个包含大约 500 列且绝大多数值为零的表似乎非常低效,而且对于除了这个一次性报告之外的其他任何东西基本上都非常麻烦。我也不想使用光标,因为我觉得这正是枢轴函数的作用,我想学习如何使用它。
  • pivot 函数需要每个列的名称,因此您仍然需要定义它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多