sql – 使用EAV表加入/透视项目

我有一张如下表所示的产品说明

╔════╦══════════════╦══════╗
║ Id ║  name        ║ price║
╠════╬══════════════╬══════╣
║  1 ║ Apple        ║ 23   ║
║  2 ║ shirt        ║  148 ║
║  3 ║ computer     ║  101 ║
║  4 ║ printer      ║  959 ║
╚════╩══════════════╩══════╝

和另一个表,其中包含由ID链接的属性

╔════╦══════════════╦══════╗
║ Id ║  attr_name   ║ Value║
╠════╬══════════════╬══════╣
║  1 ║ color        ║ red  ║
║  1 ║ size         ║  xl  ║
║  1 ║ brand        ║  App ║
║  2 ║ color        ║  blue║
║  2 ║ size         ║  l   ║
║  3 ║ color        ║  blue║
║  3 ║ size         ║  xxl ║
║  3 ║ brand        ║  HP  ║
╚════╩══════════════╩══════╝

如果我知道属性名称只是颜色大小和品牌,是否有可能带来如下表格

╔════╦══════════╦═══════╦═══════╦══════╦══╗
║ id ║   name   ║ color ║ brand ║ size ║  ║
╠════╬══════════╬═══════╬═══════╬══════╬══╣
║  1 ║ apple    ║ red   ║ app   ║ xl   ║  ║
║  2 ║ shirt    ║ blue  ║       ║ l    ║  ║
║  3 ║ computer ║ blue  ║ HP    ║ XXL  ║  ║
║  4 ║ printer  ║       ║       ║      ║  ║
╚════╩══════════╩═══════╩═══════╩══════╩══╝

最佳答案 您应该能够使用带有CASE表达式的聚合函数将行转换为列:

select d.id,
  d.name,
  max(case when a.attr_name = 'color' then a.value end) color,
  max(case when a.attr_name = 'brand' then a.value end) brand,
  max(case when a.attr_name = 'size' then a.value end) size
from product_description d
inner join product_attributes a
  on d.id = a.id
group by d.id, d.name;

SQL Fiddle with Demo.

由于您使用的是Oracle 11g,因此您可以使用PIVOT函数来获得结果:

select id, name, Color, Brand, "Size"
from
(
  select d.id, d.name,
    a.attr_name, a.value
  from product_description d
  inner join product_attributes a
    on d.id = a.id
) src
pivot
(
  max(value)
  for attr_name in ('color' as Color,
                    'brand' as Brand,
                    'size' as "Size")
) p;

SQL Fiddle with Demo

点赞