5

JOINCOUNT(*)、およびGROUP BYを使用して非常に単純なクエリを実行する正しい方法を理解しようとしています。私は実際にそれを機能させました(以下を参照)が、私が読んだことから、私はGROUP BYすべきではない余分なものを使用しています.

(注: 以下の問題は、(より複雑なテーブルを扱う) 私の実際の問題ではありませんが、類似の問題を考え出そうとしました)

私は2つのテーブルを持っています:

Table: Person
-------------
key  name     cityKey
1    Alice    1
2    Bob      2
3    Charles  2
4    David    1

Table: City
-------------
key  name
1    Albany
2    Berkeley
3    Chico

WHERE返される People (いくつかの句を含む) に対してクエリを実行したい

  • 各都市の一致人数
  • 街の鍵
  • 都市の名前。

私が行った場合

SELECT COUNT(Person.key) AS count, City.key AS cityKey, City.name AS cityName
FROM Person 
LEFT JOIN City ON Person.cityKey = City.key 
GROUP BY Person.cityKey, City.name

欲しい結果が得られる

count   cityKey   cityName
2       1         Albany
2       2         Berkeley

ただし、句の最後の部分( ) を挿入して動作させるのは間違っていると 読みました。GROUP BYCity.name

それで、これを行う正しい方法は何ですか?私は答えをグーグルで検索しようとしていますが、私が得ていない基本的な何かがあるように感じます.

4

4 に答える 4

4

この場合、都市名と都市キーの間に 1 対 1 の関係があるため、「間違っている」とは思いません。副選択に参加してキーで都市への人の数を取得し、名前の都市テーブルに再度追加するように書き直すことができますが、それがより良いかどうかについては議論の余地があります. それは私が推測するスタイルと意見の問題です。

select PC.ct, City.key, City.name
  from City
  join (select count(Person.key) ct, cityKey key from Person group by cityKey) PC
    on City.key = PC.key

私のSQLがさびていなければ:-)

于 2010-06-20T16:56:12.837 に答える
3

... GROUP BY 句の最後の部分 (City.name) を挿入して動作させるのは間違っていると読みました。

あなたは誤解しています、あなたはそれを逆手に取りました。
標準 SQLでは、集計関数でラップされていない SELECT で指定されたすべての列を GROUP BY で指定する必要があります。GROUP BY に特定の列が必要ない場合は、それらを集計関数でラップします。データベースによっては、分析/ウィンドウ機能を使用できますOVER...

ただし、MySQL と SQLite は、group by からこれらの列を省略できる「機能」を提供します。これにより、「MySQL からこのポートを fill_in_the_blank データベースに移植しないのはなぜですか?!」という終わりがありません。Stackoverflow およびその他の多数のサイトとフォーラム。

于 2010-06-20T17:00:39.620 に答える
2

ただし、GROUP BY 句の最後の部分 (City.name) を機能させるためだけに挿入するのは間違っていると読んだことがあります。

それは間違っていません。クエリ オプティマイザーがクエリをどのように認識するかを理解する必要があります。解析される順序は、「最後の部分をスローする」必要があるものです。オプティマイザーは、次のような順序でクエリを認識します。

  • 必要なテーブルが結合されている
  • 複合データセットは WHERE 句でフィルタリングされます
  • 残りの行は GROUP BY 句によってグループに分割され、集計されます
  • その後、HAVING 句を介して再度フィルター処理されます。
  • 最終的には、SELECT / ORDER BY、UPDATE、または DELETE によって操作されます。

ここでのポイントは、GROUP BY が SELECT 内のすべての列に名前を付ける必要があるということではありませんが、実際には逆です。SELECT には、GROUP BY にまだ含まれていない列を含めることはできません。

于 2010-06-20T17:00:02.803 に答える
1

Person.cityKeyグループ化して選択するため、クエリはMySQLでのみ機能しますcity.key。他のすべてのデータベースでは、 のような集計を使用するか、句min(city.key)に追加する必要があります。City.keygroup by

都市名と都市キーの組み合わせは一意であるため、以下は同等です。

select    count(person.key), min(city.key), min(city.name)
...
group by  person.citykey

または:

select    count(person.key), city.key, city.name
...
group by  person.citykey, city.key, city.name

または:

select    count(person.key), city.key, max(city.name)
...
group by  city.key

maxグループ内のすべての行は同じ都市名とキーを持つため、またはmin集計を使用するかどうかは問題ではありません。

PS複数の行がある場合でも、異なる人だけを数えたい場合は、次を試してください。

count(DISTINCT person.key)

それ以外の

count(person.key)
于 2010-06-20T16:53:11.347 に答える