【问题标题】:dynamic sql pivot table动态sql数据透视表
【发布时间】:2010-12-28 03:35:06
【问题描述】:

我希望您能帮助我解决我们的这项任务。

最初我们有这些表:

hwtype
id  name
1   router
2   switch

hwelement
id   idhwtype  name
1    1         RTR1
2    1         RTR2
3    2         SWT1

hwattributes
id  idhwtype name
1   1        speed
2   1        IP
3   2        ports

hwtypeattributes
id  idhwelement    idhwattribute value
1   1              1             100mb
2   1              2             172.16.3.23
3   2              1             10mb
4   2              2             172.16.3.26
5   3              3             8

我们现在需要的是一个以这种方式呈现数据的函数(根据 hwtype )

对于 hwtype.name =路由器

element   speed  IP
RTR1      100mb  172.16.3.23
RTR2      10mb   172.16.3.26

这个想法是让表格能够包含新的元素类型、元素和属性,而无需修改表格编码。

我一直在寻找示例,但不幸的是,我找到了可以对值进行聚合的好示例,这是我没有考虑过的。

提前感谢您的帮助

【问题讨论】:

  • 在询问有关 SQL 的问题时,请务必标明您使用的 RDBMS 品牌。例如。 sql-serveroraclemysql等。答案很重要。
  • 您不是第一个梦想通过使用实体-值架构实现无需更改数据库的系统的人。不幸的是,您最终可能也不会是最后一个诅咒该决定的人:(如果更改架构还为时不晚,您应该考虑一下。

标签: sql dynamic pivot entity-attribute-value


【解决方案1】:

您正在使用 EAV 反模式。这打破了关系数据库设计的各种规则,并且正如您所发现的,将数据取出是非常尴尬的。这种设计还有许多其他的弱点,在别处都有叙述。

阅读文章“Bad CaRMa”,了解 EAV 系统如何摧毁一家公司的精彩故事。

您必须执行以下操作才能从数据库中获取路由器属性:

SELECT e.name AS "element", 
       speedval.value AS "speed", 
       ipval.value AS "IP",
       portsval.value AS "Ports"
FROM hwtype t 
JOIN hwelement e ON (e.idhwtype = t.id)
JOIN hwattributes speed ON (speed.idhwtype = t.id AND speed.name = 'speed')
LEFT OUTER JOIN hwtypeattributes speedval 
  ON (speedval.idhwattribute = speed.id AND speedval.idhwelement = e.id)
JOIN hwattributes ip ON (ip.idhwtype = t.id AND ip.name = 'ip')
LEFT OUTER JOIN hwtypeattributes ipval 
  ON (ipval.idhwattribute = ip.id AND ipval.idhwelement = e.id)
JOIN hwattributes ports ON (ports.idhwtype = t.id AND ports.name = 'ports')
LEFT OUTER JOIN hwtypeattributes portsval 
  ON (portsval.idhwattribute = ports.id AND portsval.idhwelement = e.id)
WHERE t.name = 'router';

请注意,如果您坚持获取单行上给定元素的所有属性,则需要为每个属性添加一对额外的连接。。对于 SQL 优化器来说,这很快就会变得异常昂贵。

获取多行的属性并在应用程序代码中对其进行排序要容易得多:

SELECT e.name AS "element", a.name, v.value
FROM hwtype t 
JOIN hwelement e ON (e.idhwtype = t.id)
JOIN hwattributes a ON (a.idhwtype = t.id)
JOIN hwtypeattributes v ON (v.idhwattribute = a.id AND v.idhwelement = e.id)
WHERE t.name = 'router';

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多