如何使这种语法更好?

时间:2014-01-22 06:18:55

标签: mysql sql

好的,所以这是我感兴趣的(相当简单的)表:

|=====================
| 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 数据集上执行,最有效的解决方案是什么?

2 个答案:

答案 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子句中。为了清晰起见,现代风格将它们分开,我相信你会得到一些回复显示更现代的语法; - )

相关问题