在SQL结果集中包含动态数量的相关表行作为列的最佳方法

时间:2014-09-15 21:03:58

标签: sql

我有三个包含这样数据的表:

item表,其中包含每个项目的基本信息。每个项目都有一个“模板”,用于确定具有该模板的项目的元数据集。

id | name   | template_id
--------------------------
 1 | Thing1 | t1
 2 | Thing2 | t2

一个template_fields表,其中包含可以与具有特定模板的项目关联的每种类型的元数据的行。它看起来像下表。这里有两个模板,一个有两个字段,另一个有一个字段。 (每个模板的字段数可能不同。)

 id | key   | order
--------------------
 t1 | color | 1
 t1 | size  | 2
 t2 | year  | 1

最后,有一个meta_data表,其中包含与每个项目的模板字段关联的实际值:

item_id | template_id | key   | value
--------------------------------------
 1      | t1          | color | Red
 1      | t1          | size  | 2
 2      | t2          | year  | 2014

现在,在我的应用程序中,我希望拥有此数据的每个模板视图,这样,如果我想查看模板项目的特定模板,结果集中的每一行都包含相应模板中每个字段的列。例如,模板t1中的项目如下所示:

item_id | name   | color | size
--------------------------------
1       | Thing1 | Red   | 2

类似于模板t2中的项目

item_id | name   | year 
------------------------
1       | Thing2 | 2014

有没有办法在单个SQL查询中执行此操作? (请记住,直到运行时我才知道模板中的字段数。我也不关心包含来自具有不同模板的项目的字段的视图;一次只能使用一个模板。)

到目前为止,我对解决方案的最佳解决方法类似于下面的伪代码,但是如果您认为有更好的方法(包括更好的表格结构)来完成我想要的工作,请告诉我。

fields = SELECT template_fields.key, meta_data.value FROM template_fields 
    JOIN meta_data ON 
        meta_data.template_id = template_fields.id 
        AND meta_data.key = template_fields.key
    WHERE meta_data.item_id IN (SELECT id FROM item WHERE template='t1')
    ORDER BY meta_data.item_id, template_fields.order

items = SELECT * FROM item WHERE template='t1'

i = 0
for item in items:
    while fields[i].item_id = item.id:
        item[fields[i].key] = fields[i].value
        i += 1

这是SQL Fiddle link

一起玩

0 个答案:

没有答案