2016-10-13 6 views
2

列Aに複数の列Bが1つ以上含まれているレコードをフィルタするクエリを作成する方法?SQL - どの列の値が別の列の値と複数の組み合わせを持つレコードレコード

名簿

staffno | location | date 
---------------------------- 
sf001 | A  | 1/10/2016 
sf001 | A  | 2/10/2016 
sf001 | A  | 3/10/2016 
sf002 | A  | 1/10/2016 
sf002 | B  | 2/10/2016 
sf002 | A  | 3/10/2016 
sf003 | A  | 1/10/2016 
sf003 | A  | 2/10/2016 
sf003 | A  | 3/10/2016 

staffprofile私は見つけることが文を書いた

staffno 
------- 
sf001 
sf002 
sf003 
sf004 

は、2つのテーブルがあります:私は、下記の例により、より良い方法で問題を説明します「職員」と「所在地」の組み合わせが1つ以上あるスタッフを除外します。例えば、テーブル "ロスター"では、staffno "sf002"は複数の場所 "A"と "B"を持つので、staffno "sf002"は結果から除外されるべきです。 staffno "sf001"は単一の場所 "A"しか持たないので、これも含まれています。

は、私は次の文を書いた:sf001とsf003:

select staffno 
from roster a, staffprofile b 
where a.staffno = b.staffno 
and not exists (
    --some stmt here 
) 

結果は2つのレコードを持っている必要があります。

元は、「NOT EXISTS」を使用して、フィールドstaffnoと場所の複数の組み合わせでこれらのレコードをフィルタリングしたいと思いましたが、それらの不要なレコードを照会することはできませんでした。また、「ケース・ア・イズ」を使用しようとしましたが、異なる「ロケーション」を持つ「スタッフ・ノー」が繰り返されているものをチェックするためのステートメントを書くことに失敗しました。

さらに高度なクエリは、同じ月にレコードを持つことに加えて、上記の条件のレコードを見つけることになります。ここで

+0

SQLサーバー2005年以降、TABLE1から 'table2'をあなたの構文をサポートしていません。 [明示的な結合](http://stackoverflow.com/questions/44917/explicit-vs-implicit-sql-joins)を使用する必要があります – JohnHC

+1

@JohnHC - 'SQL SERVER 2016 'でもコンマで区切って結合します。 –

答えて

1

だけgroup byhavingを使用します。

select staffno 
from roster 
group by staffno 
having min(location) = max(location); 
+0

これは動作し、非常に明確な方法です。ありがとう! –

3

は、我々はそれが0よりも大きい場合、それはNOT EXISTS

注記で除外される各staffnoためlocationの数をチェックしているsub-query内部HAVING

SELECT staffno 
FROM staffprofile b 
WHERE NOT EXISTS (SELECT 1 
        FROM roster a 
        WHERE a.staffno = b.staffno 
        HAVING Count(DISTINCT location) > 0) 

を使用して一つの方法であります:同じstaffnoの場合は同じlocationを複製したくない場合はからDISTINCTを削除してください3210集約

+0

を使用することはお勧めできません。その文を実行すると、sf004のみが返されます。サブクエリの最後の文を "> 0"から "> 1"に変更し、 "sf001、sf003、sf004"を返します。期待どおりの結果を取得するために、メインクエリに追加のWHERE句を追加します。 –

1

あなたはスタッフがこの

SELECT staffno, 
     COUNT(distinct location) 
FROM tablename 
GROUP BY staffno 

ようそれからちょうど "1" の

SELECT staffno FROM (
    SELECT staffno, 
     COUNT(distinct location) as C 
    FROM tablename 
    GROUP BY staffno 
) AS sub 
WHERE sub.C = 1 
を取りましたどのように多くの場所数えることができます

またはHAVING

SELECT staffno 
FROM tablename 
GROUP BY staffno 
HAVING COUNT(distinct location) = 1 
0
select t1.staffno 
from staffprofile t1 
inner join 
    (
    select x1.staffno, count(distinct x1.location) loc 
    from roster x1 
    group by x1.staffno 
    having count(distinct x1.location) = 1 
    ) t2 
    on t1.staffno = t2.staffno 
0

少しサブクエリはaliassedこのクエリを説明するためには、vu名簿テーブルは、その後に参加している

/月、同じ年に複数の場所(1以上)を働いているスタッフを見つけましたあなたが言及したのと同じ月に限られていることを保証するために、StaffNo、年、月に基づくvu。

NOT EXISTSの代わりにWHERE vu.StaffNo IS NULLは、その月に1か所以下しか働いていないスタッフを制限しています。

SELECT roster.StaffNo, Year(roster.Date), Month(roster.Date) 
    FROM roster 
    LEFT JOIN (
     SELECT Year(date) year, Month(Date) month, StaffNo, COUNT(DISTINCT Location) Locations 
     FROM roster 
     GROUP BY Year(date), Month(Date), StaffNo 
     HAVING COUNT(DISTINCT Location)>1 
    ) vu 
     ON roster.StaffNo = vu.StaffNo 
     AND Year(roster.Date) = vu.year 
     AND Month(roster.Date) = vu.month 
    WHERE vu.StaffNo IS NULL 
    GROUP BY roster.StaffNo, Year(roster.Date), Month(roster.Date) 

あなたがNOT EXISTS構文を使用したい場合は、以下のクエリを使用することができます

SELECT StaffNo, Year(Date), Month(Date) 
FROM roster SingleLocationRoster 
WHERE NOT EXISTS (
    SELECT Year(date) year, Month(Date) month, StaffNo, COUNT(DISTINCT Location) Locations 
    FROM roster 
    WHERE SingleLocationRoster.StaffNo = roster.StaffNo 
    AND Year(SingleLocationRoster.Date) = Year(roster.Date) 
    AND Month(SingleLocationRoster.Date) = Month(roster.Date) 
    GROUP BY Year(date), Month(Date), StaffNo 
    HAVING COUNT(DISTINCT Location)>1 
) 
GROUP BY StaffNo, Year(Date), Month(Date) 
関連する問題