好的,所以这是我感兴趣的(相当简单的)表:
|=====================
| objects
|=====================
| id | name
|
|=====================
| properties
|=====================
| id | name
|
|====================================================
| object_properties
|====================================================
| id | object_id | property_id | value
|
我需要做的是:
这是我的SQL(实际上取得了很多东西):
SELECT *
FROM objects, properties, object_properties
WHERE
objects.name="SOME_VALUE" AND
object_properties.object_id = objects.id AND
object_properties.property_id = properties.id
看起来好不好?我究竟做错了什么?我知道我的SQL技能几乎不存在,所以我愿意接受建议!
P.S。鉴于实际查询将在 huge 数据集上执行,最有效的解决方案是什么?
答案 0 :(得分:1)
推荐的ANSI SQL-92语法是使用JOINS。
SELECT p.name,op.value
FROM objects o
INNER JOIN object_properties op
ON o.id=op.object_id
INNER JOIN properties p
ON p.id=op.property_id
WHERE o.value="SOME_VALUE"
你正在做的也是实现连接但是有一个缺点。
假设在涉及多个表的大型查询中,您错过了WHERE
子句中的连接条件。查询仍然会成功执行,因为没有连接条件,SQL将在两个表之间执行笛卡尔积,并返回超过正确行数。
但是在使用上面发布的明确提到的关键字JOIN
加入时,如果您错过了ON
子句之后指定的连接条件,则查询将从调试中为错误返回的结果集引发语法错误保存
答案 1 :(得分:1)
select properties.name, object_properties.value
from objects
where objects.name = "SOME_VALUE"
and object_properties.object_id = objects.id
and properties.id = object_properties.property_id
由于您需要属性名称和对象属性值,因此这些是我的选择列表中的唯一字段。
由于您的密钥是对象名称,因此这是在对象名称上引入过滤器的起点。
从感兴趣的实际对象,通过相关表格链接。由于object仅与object_properties相关,因此从该join开始。此连接立即使值可用。获取房产名称还需要一次加入。通过将对象属性行连接到适当的属性行来实现它,允许您访问属性名称。
顺便说一下,这种语法是“旧式”SQL,其中连接和过滤器混合到一个WHERE子句中。为了清晰起见,现代风格将它们分开,我相信你会得到一些回复显示更现代的语法; - )