2

MySQLデータベースに、「pid」の人のIDとcityその人が住んでいた都市の名前を含むテーブルがあります。すべての人が住んでいる間に複数の都市に住んでいた可能性があるため、1人の人が複数の都市を持つことができます。そのテーブルのエントリ。

PID | CITY
1   | Berlin
1   | New York

2   | Berlin
2   | Oslo
2   | New York
2   | Mexiko City

3   | Oslo

4   | Berlin
4   | Oslo
4   | Bagdad
4   | New York
4   | Mexiko City

私が知りたいことが2つまたは3つあります。

  1. 「ベルリン」と「ニューヨーク」に住んでいたすべての人の何ですかpid(結果は[1、2、4]になるはずです)
  2. かつて「ベルリン」と「ニューヨーク」に住んでいた人々が住んでいた他の都市は何ですか(結果は[「オスロ」、「メキシコシティ」、「バグダッド」になるはずです])
  3. カウント、それらの都市がテーブルに出現する頻度を取得することはさらに良いでしょう。(結果は["Oslo"-> 2、 "Mexiko City"-> 2、 "Bagdad"-> 1]になります)

これらのことを見つけるために(そしてデータベースサーバーに過度のストレスをかけないように)、クエリを設計するにはどうすればよいですか?

4

2 に答える 2

2

これらすべてを 1 つのクエリで実行できます。

SELECT
    a.pid,
    COALESCE(b.city, 'No other cities') AS othercity,
    COUNT(c.city) AS OverallCityCount
FROM
    (
        SELECT pid
        FROM tbl
        WHERE city IN ('New York', 'Berlin')
        GROUP BY pid
        HAVING COUNT(*) = 2
    ) a
LEFT JOIN
    tbl b ON a.pid = b.pid AND b.city NOT IN ('New York', 'Berlin')
LEFT JOIN
    tbl c ON b.city = c.city
GROUP BY
    a.pid, 
    b.city

FROMサブセレクトは質問 1 に答えます。ここでは、ニューヨークとベルリンの両方に住んでいた場所の s のみが取得さpidます

subselect は ごとに 1 行しか返さないため、テーブルに対してpid結果の を再び結合して、pid質問 2 に答える必要があります (pidニューヨークとベルリンの両方に住んでいた s のすべての都市を取得します)。ユーザーがニューヨークとベルリンの両方に住んでいて、他の都市には住んでいない場合、その pid を除外したくないので、LEFT JOIN. 他に都市がない場合、cityフィールドは になりますNo other cities

ここで、 に関係なく、都市がテーブル全体に何回出現するかをカウントするためpidに、フィールドで再びテーブルに自己結合しcityます。この結合が発生すると、 の組み合わせがpid -> cityテーブルにある都市の数だけ出現するので、カウントを取得するために と のGROUP BY両方を使用するpidcityCOUNT()都市が出現する回数のカウントが得られます。テーブル。が住んでいた都市が他にない場合pid、このカウントは 0 になります。

サンプル データを操作すると、結果セットは次のようになります。

pid | othercity        | OverallCityCount
-----------------------------------------
1   | No other cities  | 0
2   | Oslo             | 3
2   | Mexiko City      | 2
4   | Oslo             | 3
4   | Bagdad           | 1
4   | Mexiko City      | 2

http://www.sqlfiddle.com/#!3/2bb23/2/0

于 2012-06-25T19:06:37.807 に答える
2

1) 2 つの都市を検索しpid、リスト内の都市に一致するレコードの数を数え、一致する都市の総数と等しいかどうかを確認して、すべての都市に一致するものをすべて見つけます。

select
  pid
from
  PlacesLived
where
  city in ('Berlin', 'New York')
group by
  pid
having
  count(*) = 2

デモ: http://www.sqlfiddle.com/#!3/645ea/1


2) (1) で見つかった人々が住んでいる都市の個別のリストから、検証対象の都市 (ベルリンとニューヨーク) を除いたクエリを実行します。

select distinct
  city
from
  PlacesLived
where pid in (
  select
    pid
  from
    PlacesLived
  where
    city in ('Berlin', 'New York')
  group by
    pid
  having
    count(*) = 2
)
and city not in ('Berlin', 'New York')

デモ: http://www.sqlfiddle.com/#!3/645ea/3


3) group by と count を追加して、実際のカウントを取得します。

デモ: http://www.sqlfiddle.com/#!3/645ea/4

于 2012-06-25T19:07:19.897 に答える