2010-07-27 109 views
1

我有一個表書籍,我在那裏存放圖書資料(國際標準書號的,標題,作者等)。要知道哪些書是對方的版本,我有一個字段版本_組_ISBN,它是組中的任意ISBN。左連接不工作(MySQL的)

我無法得到這個查詢,這是爲了把書數據並根據ISBN其他版本的數量,工作:

SELECT *, Editions_Count 
    FROM Books 
LEFT JOIN ((SELECT Edition_Group_ISBN, COUNT(*) AS Editions_Count 
       FROM Books 
      WHERE Edition_Group_ISBN IN (SELECT Edition_Group_ISBN 
              FROM Books) 
      GROUP BY Edition_Group_ISBN) AS b 
     ) ON (Books.Edition_Group_ISBN = b.Edition_Group_ISBN 
      AND Books.Edition_Group_ISBN != NULL) 
    WHERE ISBN = 9780140447897 

查詢給書數據9780140447897 ,但它給出了Editions_Count AS NULL,表明LEFT JOIN不起作用。

+0

我認爲你需要另一個表來跟蹤版本分組;使用一個任意的國際標準書號來做它爲我敲響警鐘。 – staticsan 2010-07-27 00:19:59

+0

@staticsan我確實覺得用這種方式存儲它有點奇怪,但實際的缺點是什麼? – babonk 2010-07-27 00:27:47

+0

有利的一面是: 1-它的方式更容易地裝入數據到數據庫中。這將是一個獨特的ID更難 2它節省了一點的數據庫空間 – babonk 2010-07-27 00:42:03

回答

5

試試這個簡單得多查詢:

SELECT b.*, COUNT(*) AS Editions_count 
FROM Books b JOIN Books g USING (Edition_Group_ISBN) 
WHERE b.ISBN = 9780140447897 
GROUP BY b.book_id; 

我認爲你做的問題比你需要的要困難得多。您的原始查詢充滿了令人困惑的子查詢,其中至少有一個是完全多餘的。


回覆您的評論:

是的,它工作正常,以國際標準書號這種方式比較多個值:

SELECT b.*, COUNT(*) AS Editions_count 
FROM Books b JOIN Books g USING (Edition_Group_ISBN) 
WHERE b.ISBN IN (9780140447897, 9781934356555) 
GROUP BY b.book_id; 

COUNT(*)只支持純通配符*這意味着指望在所有行組。

或者您可以使用特定的語句,比如COUNT(g.Edition_Group_ISBN)這意味着指望在那裏表達被非空的組中的所有行。

但你不能使用g.*,因爲它是不明確的。它是否包括組中的所有行? (如果是這樣,只需使用COUNT(*))它是否計入組中的非空行?無論如何,這意味着什麼 - 將來自g全部列非空或其中任何列中的所有列都是非空的行數?由於這些原因,COUNT(g.*)根本不是SQL語言中的合法構造。

+1

GROUP BY子句只在MySQL中足夠;其他DBMS會讓你引用Books表中的所有列('b'別名)。由於該問題被標記爲MySQL,這不是一個直接的問題,但爲了通用性,應該注意(或者您可以將它們指向一本名爲「SQL反模式」的書)。 – 2010-07-27 01:06:49

+0

比爾,有沒有辦法使這個查詢工作與提供多個ISBN? – babonk 2010-07-27 01:16:50

+0

我試過這個,但是因COUNT(g。*)而得到一個錯誤 SELECT b。*,COUNT(g。*)AS Editions_count FROM Books b JOIN Books g USING 9780140447897) – babonk 2010-07-27 01:30:00

1

查詢似乎包括一些重言式的 - 這總是真實的陳述。

我想你可以把它簡化爲

SELECT books.*, b.Editions_Count 
    FROM Books 
LEFT JOIN ((SELECT Edition_Group_ISBN, COUNT(*) AS Editions_Count 
       FROM Books 
       GROUP BY Edition_Group_ISBN) AS b 
     ) ON (Books.Edition_Group_ISBN = b.Edition_Group_ISBN) 
WHERE ISBN = 9780140447897 

子選擇(WHERE ... IN)和聯接條件ID!= NULL是多餘的。

你可以做一個自我實現同樣的事情,參加在Edition_Group_ISBN:

SELECT b.*, count(b2.*) 
FROM Books b INNER JOIN Books b2 ON (b.Edition_Group_ISBN=b2.Edition_Group_ISBN) 
GROUP BY b.ISBN 
HAVING b.ISBN = ...; 

編輯: 解決方法是刪除JOIN條件Edition_Group_ISBN = NULL,因爲這個表達式永遠是假的! (!=的空操作數返回NLLL結果。)這會使整個連接條件爲NULL(false),因此左連接失敗。

+1

實際上'ID!= NULL'是不正確的,並且需要是'ID IS NOT NULL' – 2010-07-27 00:25:38

+0

感謝您選擇它。這可能是爲什麼它不工作。如果其中一個操作數爲NULL,則比較運算符!=返回NULL。我忙於清理第一次。 – mdma 2010-07-27 00:31:17

+0

喬治,查詢工作得益於該修復。現在我要花一些時間在選擇答案之前測試一下這裏提出的一些更好的查詢。 – babonk 2010-07-27 00:34:22