使用 EAV 表加入/透视项目

Posted

技术标签:

【中文标题】使用 EAV 表加入/透视项目【英文标题】:Join/Pivot items with EAV table 【发布时间】:2014-02-17 18:38:22 【问题描述】:

我有一个如下表,其中包含产品描述

╔════╦══════════════╦══════╗ ║身份证║姓名║价格║ ╠════╬══════════════╬══════╣ ║ 1 ║ 苹果 ║ 23 ║ ║ 2 ║ 衬衫 ║ 148 ║ ║ 3 ║ 电脑 ║ 101 ║ ║ 4 ║ 打印机 ║ 959 ║ ╚════╩══════════════╩══════╝

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

╔════╦══════════════╦══════╗ ║ ID ║ attr_name ║ 值║ ╠════╬══════════════╬══════╣ ║ 1 ║ 颜色 ║ 红色 ║ ║ 1 ║ 尺寸 ║ xl ║ ║ 1 ║ 品牌 ║ 应用程序 ║ ║ 2 ║ 颜色 ║ 蓝色║ ║ 2 ║ 尺寸 ║ l ║ ║ 3 ║ 颜色 ║ 蓝色║ ║ 3 ║ 尺寸 ║ xxl ║ ║3║品牌║HP║ ╚════╩══════════════╩══════╝

如果我知道属性名称将只有颜色大小和品牌,有什么方法可以提供如下表格

╔════╦══════════╦═══════╦═══════╦════════╕ ║ id ║ 名称 ║ 颜色 ║ 品牌 ║ 尺寸 ║ ║ ╠════╬══════════╬═══════╬═══════╬══════╬═╕ ║ 1 ║ 苹果 ║ 红色 ║ 应用 ║ xl ║ ║ ║ 2 ║ 衬衫 ║ 蓝色 ║ ║ l ║ ║ ║3║电脑║蓝色║HP║XXL║║ ║ 4 ║ 打印机 ║ ║ ║ ║ ║ ╚════╩══════════╩═══════╩═══════╩════════╕

【问题讨论】:

您真的要合并表还是要查询以显示这些值? @PatrickHofman 我想查询这些值,以便我可以从中创建一个新表。 这个结构的术语是"EAV"。 @user3199077 什么版本的Oracle? 【参考方案1】:

您应该能够使用带有 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

【讨论】:

以上是关于使用 EAV 表加入/透视项目的主要内容,如果未能解决你的问题,请参考以下文章

电子商务项目的数据库设计(我应该使用 EAV 方法)

Excle数据透视表如何重复显示行字段的项目标签

[Echarts]React项目中无法刷新数据

选择 EAV 方案中价格的所有产品

MariaDB:选择每个项目每月的平均值(数据透视表)

在 laravel 的数据透视表中存储数据