2012-11-26 62 views
0

我使用下面的MySQL语句获取Drupal的帖子,其中ID匹配跨表:WHERE和语句在MySQL

SELECT node.nid,node_revisions.nid,url_alias.nid, 1, FROM_UNIXTIME(node.created), node_revisions.body, node_revisions.title, node_revisions.teaser, url_alias.slug, FROM_UNIXTIME(node.changed), if(node.type='blog', 'post', 'page') 
FROM node, node_revisions, url_alias 
WHERE (node.type='blog' OR node.type='page') 
AND (node.nid=node_revisions.nid) 
AND (node.nid=url_alias.nid) 
LIMIT 10; 

(请注意,我已经做了一些修改url_alias,如果有人在尝试要复制这个)

我必须使用两个和声明,因为,出于某种原因,这是行不通的:

... 
WHERE ... 
AND (node.nid=node_revisions.nid=url_alias.nid) 
... 

为什么我不能比拟的ID在一个声明呢?

回答

4

SQL不能像那样工作。 MySQL只接受一对二进制比较。大多数编程语言都会像你想要的那样工作,但是SQL不是一种编程语言。明确编写连接将有助于查询的可读性,并可能是您正在尝试执行的工作。查询可以改写这样的:

SELECT nid, 1, FROM_UNIXTIME(node.created), node_revisions.body, node_revisions.title, 
    node_revisions.teaser, url_alias.slug, FROM_UNIXTIME(node.changed), 
    if(node.type='blog', 'post', 'page') 
FROM node 
    JOIN node_revisions USING (nid) 
    LEFT JOIN url_alias USING (nid) 
WHERE node.type IN ('blog','page') 
LIMIT 10 

我也改变了三种nid列中选择一个,因为永远是一样的,发的帖子类型条件的IN条款,因为优化更好,并取得了在节点没有别名的情况下,JOINurl_aliases a LEFT JOIN

+0

这看起来真棒。我还没有使用JOIN,或者是LEFT JOIN,所以我还没有真正理解它,但它似乎更具可读性,我同意。谢谢! – bozdoz

+0

这是一个很好的解决方案,但不是一个好的答案。其他答案实际上是详细说明为什么我无法在一个AND语句中比较ID。你可以将这个添加到你的答案,所以我可以标记你的正确吗? – bozdoz

+0

@bozdoz我为您的原始问题添加了更深入的答案。 –

2

SQL中的=比较器是二进制的。 a = b = c在任何情况下都不允许。

1

我会说你提供的语法可以用几种方法解释。

你开车在直观人的方式,在其中您可以编写相当于

(node.nid=node_revisions.nid) AND (node_revisions.nid=url_alias.nid) 

和方式的计算机可能会将它只是寻址操作左至右:

(node.nid=node_revisions.nid)=url_alias.nid 

也就是说,要分析url_alias.nid是否等于上一次相等的真/假(在本例中为真0/1)结果。这不是微不足道的,布尔运算的结果经常被当作变量,并直接用这种方式进行比较。

1

在编程语言(SQL虽然不是一个)进行比较会返回一个布尔值,并加括号的多计算由尊重迹象的订单,然后由左到右。所以,如果它是PHP

$a == $b == 3将汇编成
($a == $b) == 3这将汇编成
true == 3false == 3相应