2011-10-13 84 views
1

我可以通過此查詢獲得一些幫助。我會詳細解釋。爲了更容易,我將以HTML標籤和屬性爲例。MySQL查詢建議請求

我有3個表:

  • TBL 1 - 包含了所有的HTML標籤(tagIdtagName
  • tbl2的 - 包含了所有可能出現的 標籤可用屬性(attIdattName
  • TBL3 - 是一個映射表TBL1和TBL2(tagIdattId

我想要選擇屬於所選標籤(在標籤ID爲4的示例中)和標籤ID的所有屬性(以及有關屬性的相關信息)。

這裏是我想從查詢得到什麼一個例子:

attId tagId attName 
50  4  The name of the attribute with id 50 
89  4  The name of the attribute with id 89 
114 4  The name of the attribute with id 114 

下面是我做了查詢,但我相信有一個更好的辦法。

SELECT tbl2.*, tbl3.tagId 
FROM tbl2 JOIN tbl3 
WHERE tbl3.attId IN (
    SELECT tbl3.attId FROM tbl3 where tbl3.tagId=4 
    ) 
AND tbl3.attIdd = tbl2.attId 
GROUP BY tbl3.attId 

在此先感謝。

回答

3

1期
你做的交叉連接,你以後減少到內連接放一個過濾器where子句。
這是使用隱式連接語法時的舊手法。
在大多數SQL方言(但不是MySQL)上,這會產生錯誤。
切勿在沒有ON子句的情況下進行連接
如果你想要做一個交叉連接,使用此語法:select * from a cross join b

第2期
選擇真的不需要子,你可以做測試where子句中。

SELECT tbl2.*, tbl3.tagId 
FROM tbl2 
INNER JOIN tbl3 ON (tbl3.attIdd = tbl2.attId) 
WHERE tbl3.tagId = 4 
GROUP BY tbl3.attId 

問題3A
你被上tbl3.ATTid,這在該上下文中是一樣的上tbl2.attid(因爲ON (tbl3.attIdd = tbl2.attId)子句)
後者品牌做一組通過執行一組多一點意義,因爲你正在做select tbl2.*,不select tbl3.*

問題3B
如果 attId不是tbl2的主鍵或唯一鍵,那麼查詢的結果將是不確定的。
這意味着查詢將從具有相同attID的可能行列表中隨機選擇一行。如果你不想要,你將不得不包含一個having子句,它將根據某些標準選擇一行。

/*selects the most recent row per attID, instead of a random one*/ 
SELECT tbl2.*, tbl3.tagId 
FROM tbl2 
INNER JOIN tbl3 ON (tbl3.attIdd = tbl2.attId) 
WHERE tbl3.tagId = 4 
GROUP BY tbl2.attId 
HAVING tbl2.dateadded = MAX(tabl2.dateadded) 
+0

感謝很多驚人的答案。顯然我需要閱讀更多關於JOIN的內容。再次感謝。 – Boris

1

你可以像下面這樣做吧。

SELECT tbl2.*, tbl3.tagId 
FROM tbl2 JOIN tbl3 
ON tbl3.attId = tbl2.attId 
WHERE tbl2.tagId = <selected id> 
GROUP BY tbl3.attId 
-1
SELECT tbl2.attId, tbl1.tagId, tbl2.attName FROM tbl3, tbl1, tbl2 
    WHERE tbl1.tagId = tbl3.tagId AND tbl2.attId = tbl3.attId AND tbl3.tagId = 4 
+0

-1,隱式連接是一種反模式,用tbl1怎麼樣? – Johan