2011-12-27 16 views
1

EDIT:同じIDを持つ行を検索し、特定の名前を持つ

私はこのように3行のテーブルを持っています。私はIDのウィッヒを見つけたい

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 

は、名前の特定のセットを持っており、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

これは、関係分割と呼ばれます。 –

答えて

5

最も簡単な方法は、あなたのリスト内の要素の数とIDごとにCOUNTを比較することです:

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

注:ORDER BYが必要と

を必要に応じてした後行くされていません

質問の更新を伴う編集。 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、簡単です:

GBNと同様に
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

+1

OPが正確な分割を望んでいるようです。 –

+1

質問を編集しました。私はあなたの答えを考えましたが、言及するのを忘れた問題の追加の制約のためにそれをしませんでした –

1

、しかしを可能にID /名前の重複の可能性:

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

OKAY!...私は私の問題を解決しました!私はIN節を使って検索テーブルを使わずにGBNのロジックを変更しました

MAX(rev)= MIN(REV)を実行すると1つの脆弱性があります。

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) 

のようなクエリを使用する場合minとmaxが異なっており、カウントが3

ので、私は単純に追加しているとして、それは私にID 1を表示しません。 GROUPBY

に別の列は、最終的なクエリは

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

ありがとうございました。 !

+0

私は思ったよりも簡単でした! –

関連する問題