【问题标题】:How can I convert an EAV schema to a normal schema using PIVOT?如何使用 PIVOT 将 EAV 模式转换为普通模式?
【发布时间】:2019-12-11 13:06:44
【问题描述】:

我有一个名为 SourceTable 的表,其中有 4 个字段。 Properties_title 字段有 3 个值(AAA、BBB、CCC),但也可以有更多。取决于它们中的每一个,NumericValue 字段和Property_item_title 字段都有一个值。根据下表,如果Properties_title 是 AAA 或 CCC,那么 Property_item_title 它有值,如果 Properties_title 是 BBB,那么NumericValue 它有价值。 现在我想旋转它,为每个 W_ID 制作一行,例如 Result Table。

源表:

+--------+------------------+---------------+---------------------+
|  W_ID  | Properties_title | NumericValue  | Property_item_title |
+--------+------------------+---------------+---------------------+
| 102859 |     AAA          | null          |  Useless            |
| 102859 |     BBB          | 30000         |  null               |
| 102859 |     CCC          | null          |  Repair             |
| 92527  |     AAA          | null          |  Use                |
| 92527  |     BBB          | 3250          |  null               |
+--------+------------------+---------------+---------------------+

结果表:

+-------+-----------+---------+---------+
|  W_id |   AAA     |  BBB    | CCC     |
+-------+-----------+---------+-------- +
|102859 |  Useless  | 30000   |  Repair |
|92527  |  Use      | 3250    |  null   |
|...    |    ...    | ...     |  ...    |
+-------+-----------+---------+---------+

列名必须是动态的

我的代码:

CREATE TABLE dbo.SourceTable (W_ID int NOT NULL,
                            Properties_title varchar(3) NOT NULL,
                            NumericValue int NULL,
                            Property_item_title varchar(100) NULL);

INSERT INTO dbo.SourceTable
VALUES (102859,'AAA',NULL,'Useless'),
       (102859,'BBB',30000,NULL),
       (102859,'CCC',NULL,'Repair'),
       (92527,'AAA',NULL,'Use'),
       (92527,'BBB',3250,NULL);

SELECT *
FROM dbo.SourceTable;

Here 是一个 dbfiddle。

感谢您的帮助。

【问题讨论】:

  • 这能回答你的问题吗? SQL Server dynamic PIVOT query?
  • @panagiotis-kanavos 不完全是,但它是如此接近。
  • 为什么不呢,@JavedAbedi?我看不出有什么明显的原因。
  • @larnu 因为我有两个带有值的文件,代码应该识别哪个值是哪个列。
  • 这种说法毫无意义。对我来说,这建议重复,看起来它可以与 ISNULL 一起使用。

标签: sql sql-server tsql pivot entity-attribute-value


【解决方案1】:

要在列的固定列表上进行透视,您可以进行条件聚合:

select 
    w_id,
    max(case when properties_title = 'AAA' then property_item_title end) aaa,
    max(case when properties_title = 'BBB' then numeric_value end) bbb,
    max(case when properties_title = 'CCC' then property_item_title end) ccc
from sourcetable
group by w_id

【讨论】:

  • 无论谁投反对票,PIVOT 不需要 less 代码而不是条件聚合,也没有任何方式更好或更快
  • 您有硬编码的列标题。假设 OP 已发布示例数据,当有第四个值说“DDD”时,此查询将不起作用
  • @PratikBhavsar:确实,这就是为什么我提到它以 fixed 列列表为中心(PIVOT 具有相同的限制)。 OP 没有说明列名必须是动态的。而要使其成为动态的,我们需要动态 SQL,这似乎超出了问题的范围。
  • @PratikBhavsar 这也是 PIVOT 所做的。如果事先不知道列名,就无法在查询中使用 PIVOT。事实上,如果事先不知道列,就无法编写 any 查询。 * 只是返回所有列名称的快捷方式
  • @gmb 正是我的朋友,列名必须是动态的
猜你喜欢
  • 2011-08-06
  • 2012-10-20
  • 2020-01-17
  • 2021-06-10
  • 2017-07-08
  • 2014-04-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多