嚴重編輯!MYSQL連接結果集在IN()where子句中設置了擦除結果嗎?
最初的問題是基於對IN()如何處理來自連接結果集的列的誤解。我認爲IN(some_join.some_column)會將結果列視爲列表並循環遍歷每行。事實證明它只看第一行。
所以,適應的問題:MySQL中是否有任何可以循環訪問WHERE子句中的連接結果列?
下面是我正在使用的超簡化代碼,從複雜的crm搜索功能中剝離下來。左連接和一般想法是來自該查詢的遺留物。所以對於這個查詢,它必須是一個獨家搜索 - 找到所有指定標籤的人,而不是任何人。
首先DB
表1:人
+----+------+
| id | name |
+----+------+
| 1 | Bob |
| 2 | Jill |
+----+------+
表2:標籤
+-----------+--------+
| person_id | tag_id |
+-----------+--------+
| 1 | 1 |
| 1 | 2 |
| 2 | 2 |
| 2 | 3 |
+-----------+--------+
尼斯和簡單。所以,自然:
SELECT name, GROUP_CONCAT(tag.tag_id) FROM person LEFT JOIN tag ON person.id = tag.person_id GROUP BY name;
+------+--------------------------+
| name | GROUP_CONCAT(tag.tag_id) |
+------+--------------------------+
| Bob | 1,2 |
| Jill | 2,3 |
+------+--------------------------+
到目前爲止好。所以我在尋找的是在第一種情況下只能找到Bob,而在第二種情況下只能找到Jill的情況 - 不使用HAVING COUNT(DISTINCT ...),因爲這在更廣泛的查詢中不起作用(有單獨的標籤繼承緩存和大量其他東西)。
這是我的原始示例查詢 - 基於IN()會一次遍歷所有行的錯誤想法。
SELECT DISTINCT name FROM person LEFT JOIN tag ON person.id = tag.person_id
WHERE ((1 IN (tag.tag_id)) AND (2 IN (tag.tag_id)));
Empty set (0.00 sec)
SELECT DISTINCT name FROM person LEFT JOIN tag ON person.id = tag.person_id
WHERE ((2 IN (tag.tag_id)) AND (3 IN (tag.tag_id)));
Empty set (0.00 sec)
這是我的新最新的嘗試失敗給什麼我的目標......
SELECT name, GROUP_CONCAT(tag.tag_id) FROM person LEFT JOIN tag ON person.id = tag.person_id
GROUP BY person.id HAVING ((1 IN (GROUP_CONCAT(tag.tag_id)))) AND (2 IN (GROUP_CONCAT(tag.tag_id)));
Empty set (0.00 sec)
所以看起來它採取GROUP_CONCAT串,任1,2或2個主意,3,並將其視爲單一實體而不是表達式列表。有沒有辦法將分組列轉換爲IN()或= ANY()將視爲列表的表達式列表?
本質上,我試圖使IN()循環迭代地處理類似於數組或動態表達式列表的東西,該列表包含來自聯接的所有數據行。
所以多一點測試,看起來這些結果是相同的,如果我使用=而不是IN。所以,也許MySQL優化器正在將我的'IN'轉換爲'=',看到這給出了「P = X AND P = Y」,並因此返回了幾乎沒有觸及數據庫的空結果集 - 因此超級快速響應時間<0.01秒? – user568458 2011-01-10 16:44:27
超快響應時間可能是由於WHERE條件永遠不會成立,因此不需要讀取任何行。看到喬的回答。 – 2011-01-10 16:50:16