如何在SQL数据库中使用rows-as-fields

时间:2010-10-07 18:31:13

标签: sql row entity-attribute-value

我有一个关于一般数据库结构的SQL相关问题似乎有些常见。有一天我试图解决一个问题,然后(后来)我看到其他人做了同样的事情(或者非常相似的事情),所以我认为结构本身是有意义的。我只是在尝试对它形成某些查询时遇到了麻烦。

这个想法是你有一个包含“items”的表,你想为每个项目存储一组字段及其值。通常这可以通过简单地向items表添加列来完成,问题是字段本身(不仅仅是值)因项目而异。例如,我可能有两个项目:

第1条 product_id = aproductid
hidden_​​key = ahiddenkeyvalue
第2条
product_id = anotherproductid
地址= anaddress

您可以看到两个项目都有product_id字段(具有不同的值),但每个项目存储的数据不同。

数据库中的结构最终会是这样的:

ItemsTable
ID
itemdata_1
itemdata_2
...

FieldsTable
ID
FIELD_NAME
...

与他们相关并使其有效的表格

FieldsItemRelationsTable
FIELD_ID
ITEM_ID

<小时/> 好吧,当我尝试做一些只涉及一个“动态场”值的事情时,没有问题。我通常做类似的事情:

SELECT i.* FROM ItemsTable i
INNER JOIN FieldsItemRelationsTable v ON v.item_id = i.id
INNER JOIN FieldsTable f ON f.id = v.field_id
WHERE v.value = 50 AND f.name = 'product_id';

选择product_id = 50

的所有项目

当我需要做一些涉及多个“动态字段”值的事情时,会出现问题。假设我想选择product_id = 50 AND hidden_​​key = 30的所有项目。是否可以使用单个SQL语句?我试过了:

SELECT i.* FROM ItemsTable i
INNER JOIN FieldsItemRelationsTable v ON v.item_id = i.id
INNER JOIN FieldsTable f ON f.id = v.field_id
WHERE (v.value = 50 AND f.name = 'product_id')
AND (v.value = 30 AND f.name = 'hidden_key');

但它只返回零行。

3 个答案:

答案 0 :(得分:2)

您需要为要带回的每个值单独加入...

SELECT i.* FROM ItemsTable i 
INNER JOIN FieldsItemRelationsTable v ON v.item_id = i.id 
INNER JOIN FieldsTable f ON f.id = v.field_id 
INNER JOIN FieldsItemRelationsTable v2 ON v2.item_id = i.id 
INNER JOIN FieldsTable f2 ON f2.id = v2.field_id 
WHERE v.value = 50 AND f.name = 'product_id'
AND (v2.value = 30 AND f2.name = 'hidden_key'); 

呃...那个查询可能无法运行(我的部分复制/粘贴污泥工作),但你明白了......你需要在表的第二个实例中保存的第二个值(s)(我的例子中的v2和f2)与第一个实例分开。 v1.value = 30和v2.value = 50. v1.value = 50和v1.value = 30永远不应该返回行,因为没有任何东西同时等于30和50

作为一个想法...如果你把where子句放在join语句

中,查询可能会更容易阅读
SELECT i.* FROM ItemsTable i 
INNER JOIN FieldsItemRelationsTable v ON v.item_id = i.id and v.value = 50 
INNER JOIN FieldsTable f ON f.id = v.field_id and f.name = 'product_id'
INNER JOIN FieldsItemRelationsTable v2 ON v2.item_id = i.id and v2.value = 30 
INNER JOIN FieldsTable f2 ON f2.id = v2.field_id and f2.name = 'hidden_key'

在功能上,两个查询都应该运行相同。我不确定是否存在逻辑限制......在调度系统中,您经常会看到“异常”的设置...我有一个报告查询,这样加入了28次...每个例外一个返回类型。

答案 1 :(得分:1)

很抱歉含糊不清,但我会更多地调查你的选择。

答案 2 :(得分:0)

尝试做一些左或右连接,看看你是否得到任何结果。如果有空字段,内部联接有时不会返回结果。

这是一个开始。

不要忘了,外连接=笛卡儿产品