2015-04-04 98 views
1

在我正在開發的圖書管理系統中,我有一個有文學流派樹的表格。它們被編碼爲IP(代碼2,詩歌,代碼2.1,史詩,代碼2.1.2,拉丁史詩等)。JOIN查詢的奇怪行爲

類似IP的代碼允許計數不僅僅是一個特定的流派,而且它的所有子類都可以計數。如果我想知道庫中有多少首詩,我需要做的就是計算2.%代碼。由於樹會根據圖書館的需要進行填充,當他們獲得新書籍時,會有一個名爲ord_vis的字段指定行的可視化順序(即關於意大利 - 土耳其戰爭的新行必須在第一次世界大戰和第二次世界大戰之前出現,即使在六天戰爭之後插入)。

樹工作順利,直到我決定用下面的查詢來算的圖書數量:

SELECT a.id, a.code, a.level, a.parent, a.text, 
     GROUP_CONCAT(b.text ORDER BY b.ord_vis SEPARATOR ', ') AS subs, 
     COUNT(books.id) AS total 
    FROM tree AS a 
    LEFT JOIN books ON books.code LIKE CONCAT(a.code, '%') 
    LEFT JOIN tree AS b ON b.parent = a.id 
     AND b.level = a.level +1 
    WHERE a.parent =42 -- this value is the user query 
    GROUP BY a.id 
    ORDER BY a.ord_vis ASC 

奇怪的是,如果total> 0或NOT NULL,顯示的subs的數量是相同的total:有6本書和3個subgenres,我得到sub,比如「sub1,sub1,sub2,sub2,sub3,sub3」。

total爲0時,subs顯示爲正確的編號和順序。

我沒有成功地測試過所有JOIN選項可用的查詢,並且我還嘗試更改JOIN和SELECT字段的順序。

我解決了修改獲得這種潛水艇的方式的問題:GROUP_CONCAT(DISTINCT b.text ORDER BY b.ord_vis SEPARATOR ', ') AS subs但我想明白爲什麼我得到那些奇怪的結果沒有DISTINCT

任何線索?

+0

你可以做腳本計算(我懷疑LEFT是不必要的?)?例如php – 2015-04-04 08:14:34

+0

結果很好,在分組中添加DISTINCT ...但我想明白爲什麼:-) – 2015-04-04 08:27:51

+0

爲了知道DISTINCT爲什麼影響你的分組(這看起來並不奇怪),我需要查看你的數據。 – 2015-04-04 08:30:08

回答

1

JOIN傾向於爆炸的行數。 DISTINCT是一種統治爆炸的方法。

另一種方法(有時可行)對我們來說是一個相關的子查詢。這可能(也可能不會)運行速度較慢:

SELECT a.id, a.code, a.level, a.parent, a.text, 
     (SELECT GROUP_CONCAT(text ORDER BY ord_vis SEPARATOR ', ') 
      FROM tree 
      WHERE parent = a.id 
       AND level = a.level +1) AS subs, 
     COUNT(books.id) AS total 
    FROM tree AS a 
    LEFT JOIN books ON books.code LIKE CONCAT(a.code, '%') 
    WHERE a.parent =42 -- this value is the user query 
    GROUP BY a.id 
    ORDER BY a.ord_vis ASC 

+0

讓我感到困惑的是沒有不同。我不認爲在10,000本書上搜索子查詢將會產生很大的差異,但是我會在有大約120,000行的測試平臺上嘗試它。沒有左邊沒有書籍的流派沒有被顯示。 – 2015-04-04 20:21:57

+0

如果您在沒有DISTINCT的情況下執行SELECT,您可能會感受到它。你會看到幾乎重複的行出來。它們只會因爲其中一個JOIN而有所不同。如果您還刪除該JOIN,則不再需要DISTINCT。 (對不起,我有點模糊。) – 2015-04-05 01:18:15

+0

我看到我必須添加一個DISTINCT,即使在COUNT(書籍。id),因爲我在10,000行的桌子上總共獲得了超過80,000個標題:一種龐氏騙局...... :-) – 2015-04-05 02:56:03