Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/unix/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将动态数量的相关表行作为列包含在SQL结果集中的最佳方法_Sql - Fatal编程技术网

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

将动态数量的相关表行作为列包含在SQL结果集中的最佳方法,sql,Sql,我有三个数据如下的表: item_id | name | color | size -------------------------------- 1 | Thing1 | Red | 2 包含每个项目基本信息的项目表。每个项目都有一个“模板”,用于确定具有该模板的项目的一组元数据 id | name | template_id -------------------------- 1 | Thing1 | t1 2 | Thing2 | t2 id | ke

我有三个数据如下的表:

item_id | name   | color | size
--------------------------------
1       | Thing1 | Red   | 2
包含每个项目基本信息的
项目
表。每个项目都有一个“模板”,用于确定具有该模板的项目的一组元数据

id | name   | template_id
--------------------------
 1 | Thing1 | t1
 2 | Thing2 | t2
 id | key   | order
--------------------
 t1 | color | 1
 t1 | size  | 2
 t2 | year  | 1
一个
template\u字段
表,其中包含每种元数据类型的一行,这些元数据可能与具有特定模板的项相关联。看起来有点像下表。这里有两个模板,一个有两个字段,另一个有一个字段。(每个模板的字段数可能不同。)

最后,还有一个
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

这里有一个游戏

您正在寻找的被称为
EAV模式
:。然而,这种模式有许多缺点,当涉及到搜索或排序时,因为您无法使用本机SQL命令来实现这一点。特别是,当您想要将值表转换为实际列(最有可能执行排序或搜索)时,您将遇到性能问题,因为每一列都是一个额外的连接,您需要使用一些聚合方法来消除空值。(被称为“Max Hack”)这可能会给你一个想法-