2011-12-27 72 views
1

編輯:查找具有相同ID的行,並有一組特定的名稱

我有一張3行像這樣的表格。

ID NAME REV 
1  A 0 
1  B 0 
1  C 0 
2  A 1 
2  B 0 
2  C 0 
3  A 1 
3  B 1 

我想找到ID至極有一組特定的名稱和REV爲同一 例如: EDIT2:GBN的解決方案就是很好的工作,但因爲我沒有獲得創建新表。增加的限制是不能創建新的表格。

if input = A,B then output is 3 
if input = A ,B,C then output is 1 and not 1,2 since the rev level differs in 2. 
+1

這被稱爲關係分割。 – 2011-12-27 13:41:29

回答

5

最簡單的方法是每個ID的計數比較與您的列表中元素的個數:

SELECT 
    ID 
FROM 
    MyTable 
WHERE 
    NAME IN ('A', 'B', 'C') 
GROUP BY 
    ID 
HAVING 
    COUNT(*) = 3; 

注意:訂單是不需要的,如果需要

在HAVING後進入

編輯問題更新。在MySQL中,它更容易使用一個單獨的表的搜索字詞

DROP TABLE IF EXISTS gbn; 
CREATE TABLE gbn (ID INT, `name` VARCHAR(100), REV INT); 
INSERT gbn VALUES (1, 'A', 0); 
INSERT gbn VALUES (1, 'B', 0); 
INSERT gbn VALUES (1, 'C', 0); 
INSERT gbn VALUES (2, 'A', 1); 
INSERT gbn VALUES (2, 'B', 0); 
INSERT gbn VALUES (2, 'C', 0); 
INSERT gbn VALUES (3, 'A', 0); 
INSERT gbn VALUES (3, 'B', 0); 

DROP TABLE IF EXISTS gbn1; 
CREATE TABLE gbn1 (`name` VARCHAR(100)); 
INSERT gbn1 VALUES ('A'); 
INSERT gbn1 VALUES ('B'); 

SELECT 
    gbn.ID 
FROM 
    gbn 
    LEFT JOIN 
    gbn1 ON gbn.`name` = gbn1.`name` 
GROUP BY 
    gbn.ID 
HAVING 
    COUNT(*) = (SELECT COUNT(*) FROM gbn1) 
    AND MIN(gbn.REV) = MAX(gbn.REV); 

INSERT gbn1 VALUES ('C'); 

SELECT 
    gbn.ID 
FROM 
    gbn 
    LEFT JOIN 
    gbn1 ON gbn.`name` = gbn1.`name` 
GROUP BY 
    gbn.ID 
HAVING 
    COUNT(*) = (SELECT COUNT(*) FROM gbn1) 
    AND MIN(gbn.REV) = MAX(gbn.REV); 

編輯2,無需額外的表,使用派生的(內置)表:

SELECT 
    gbn.ID 
FROM 
    gbn 
    LEFT JOIN 
    (SELECT 'A' AS `name` 
    UNION ALL SELECT 'B' 
    UNION ALL SELECT 'C' 
    ) gbn1 ON gbn.`name` = gbn1.`name` 
GROUP BY 
    gbn.ID 
HAVING 
    COUNT(*) = 3 -- matches number of elements in gbn1 derived table 
    AND MIN(gbn.REV) = MAX(gbn.REV); 
+1

@David Stratton:你的ORDER BY在錯誤的地方。如果您使用SQL_MODE「ONLY_FULL_GROUP_BY」,則會失敗。 – gbn 2011-12-27 13:45:51

+1

OP似乎想要精確的劃分。 – 2011-12-27 13:45:54

+1

編輯過這個問題。我沒有想到你的答案,但沒有做到這一點,因爲在我忘記提及的問題中增加了限制 – 2011-12-27 13:51:08

1

類似GBN,但考慮到重複ID /名稱組合的可能性:

SELECT ID 
FROM MyTable 
WHERE NAME IN ('A', 'B', 'C') 
GROUP BY ID 
HAVING COUNT(DISTINCT NAME) = 3; 
1

OKAY!...我解決了我的問題!我修改了GBN的邏輯,在沒有使用IN子句的搜索表的情況下執行此操作。

MAX MAX(rev)= MIN(REV)的缺陷是:如果我有這樣的數據。

ID NAME REV 
1  A  0 
1  B  1 
1  A  1 

然後當我使用查詢像

Select ID from TABLE 
where NAME in {A,B} 
groupby ID 
having count(*) = 2 
and MIN(REV) = MAX(REV) 

它不會告訴我ID 1作爲最小值和最大值是不同的,計爲3

所以我只需添加另一列於GROUPBY

所以最終的查詢是

Select ID from TABLE 
where NAME in {A,B} 
groupby ID,REV 
having count(*) = 2 
and MIN(REV) = MAX(REV) 

謝謝,所有幫助。 !

+0

這比我想象的更簡單! – 2011-12-28 09:57:13

相關問題