【问题标题】:How can I create a table using distinct values from a column as the column names for the new table?如何使用列中的不同值作为新表的列名来创建表?
【发布时间】:2013-05-11 11:13:37
【问题描述】:

我有一个带有标签列的表,其中包含大约 1000 个不同的标签。我想为每个不同的标签创建一个包含一列的新表,列名将是标签值。使用 T-SQL 是否有一种简单易用的方法来做到这一点? SQL Server 2005 及更高版本中的任何内容都可以。

这是我的意思的一个例子:

Table:
Tag    Value    Timestamp
tag1   123      ---
tag1   456      ---
tag2   854      ---
tag3   923      ---
 .
 .
 .
tag90  324      ---

New Table:
tag1    tag2    tag3 ... tag90
123     854     923      324
456 ...

更新:

我知道限制(表中的列数),但是列不会稀疏,并且任何列中都不会有空值或 0 值。

我想要这个表的原因是我想针对这个新表的列运行 SSAS 聚类算法。

【问题讨论】:

  • 为什么需要将数据存储在1000列的表中?如果您需要以该格式显示数据,则可以 PIVOT。将数据存储在 1000 列中是个坏主意。
  • 我的观点是,有一些方法可以将数据转换为您想要的格式,而无需将其存储在 1000 列中。
  • @SpaceghostAli 几乎没有充分的理由将数据存储在 1000 列中。
  • @SpaceghostAli 这通常是个坏主意,不管这个问题的答案如何。顺便说一句,你还没有回答。
  • 好的,我已经用新信息更新了您的问题(最好添加信息 - 这对回答问题很有用 - 在问题中而不是在 cmets 中。)并非所有人都会阅读所有的 cmets。

标签: sql sql-server tsql pivot


【解决方案1】:

使用PIVOT 表运算符,然后使用INTO 子句从透视列创建一个新表。像这样的:

SELECT *
INTO newtablename
FROM ( SELECT tag, value FROM tags) AS t
PIVOT 
(
  MIN(value)
  FOR tag in ([tag1], [tag2], [tag3], [tag4])
) AS p;

在这里查看它的实际效果:


但是, 在您的情况下,您必须使用动态 sql 为表中的任意数量的标签动态地执行此操作,而不是手动列出它们。像这样:

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


select @cols = STUFF((SELECT distinct ',' +
                        QUOTENAME(tag)
                      FROM tags
                      FOR XML PATH(''), TYPE
                     ).value('.', 'NVARCHAR(MAX)') 
                        , 1, 1, '');

SELECT @query = 'SELECT *
                 INTO newtablename
                 FROM ( SELECT tag, value FROM tags) AS t
                 PIVOT 
                 (
                   MIN(value)
                   FOR tag in ( ' + @cols + ' )
                 ) AS p';

execute(@query);

在这里查看它的实际效果:

这将创建一个名为 newtablename 的全新表,如下所示:

| TAG1 | TAG2 | TAG3 | TAG4 |
-----------------------------
|  123 |  854 |  923 |   44 |

【讨论】:

  • 一个建议是在子查询中添加row_number() over(partition by tag order by value),否则每个标签只会得到一行,并且每个标签可能有多个值。
  • 快速尝试了这种方法,它似乎可以解决问题
  • +1 。 . .我很高兴你取消了这个。对于 OP 的要求,原始答案看起来是正确的。
【解决方案2】:

普通 SQL Server 表中的最大列数为 1,024(请参阅here)。

您的请求已危险地接近限制。因此,尽管在技术上是可行的,但强烈不建议这样做。 Mahmoud's answer 似乎适用于此目的。

如果大多数值为 0/NULL,您可以调查包含“稀疏列”的称为“宽表”的东西。

如果您解释了为什么要执行此支点,那么您的问题可能还有其他解决方案。

我非常同情想要用 SQL 中的数据进行数据分析。在这里,通用选项:

  1. 将数据导入 SAS、SPSS 或 R。这些对列数没有任意限制。

  2. 将这些值连接到一个列中,可能用逗号分隔。然后可以很容易地将其引入另一个工具。

  3. 使用对列数有较高限制的数据库,例如 Oracle 或 MySQL(仍然有较低的限制,但要好一些)。

  4. 使用称为垂直分区的技术将列放在单独的表中。由 Vertica 等数据库直接支持。可以由其他数据库实现。但是,您会遇到查询中允许的最大列数的问题。

对于您的特定问题,我强烈建议您研究聚类算法。 K-means 可能不会在如此广泛的数据上给出很好的结果。我不知道 SSAS 是否支持 EM 集群,这可能会更好一些。您可以尝试将分析转换为关联规则问题。但严肃的方法是使用主成分转换数据并在低维空间中进行聚类。

【讨论】:

  • 我知道限制,但是列不会稀疏,任何列中都不会有空值或 0 值。这些列将包含来自 DRI 工厂仪器的数据。我想针对这个新表的列运行 SSAS 聚类算法。
  • 感谢您的意见。如果这不适用于 SQL 和 SSAS(我的选择是因为熟悉),我想我会探索您在此处列出的一些选项以及 Hadoop
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-07-15
  • 1970-01-01
  • 1970-01-01
  • 2018-05-05
  • 1970-01-01
  • 1970-01-01
  • 2021-12-16
相关资源
最近更新 更多