2012-11-26 63 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相應