私は自分自身にいくつかのSQLにこだわっています。質問を見事に表現できるとは思わないので、お見せしましょう。
2つのテーブルがあります。1つは人と呼ばれ、もう1つは予定と呼ばれます。私は人が持っている予定の数(彼らがゼロを持っている場合を含む)を返そうとしています。予定にはperson_id
が含まれ、予定ごとにperson_id
があります。したがって、COUNT(person_id)
は賢明なアプローチです。
クエリ:
SELECT person_id, COUNT(person_id) AS "number_of_appointments"
FROM appointment
GROUP BY person_id;
Person_idが持つ予定の数を正しく返します。ただし、アポイントメントが0の人は返されません(明らかに、そのテーブルにはないため)。
ステートメントを調整してpersonテーブルからperson_idを取得すると、次のようになります。
SELECT person.person_id, COUNT(appointment.person_id) AS "number_of_appointments"
FROM appointment
JOIN person ON person.person_id = appointment.person_id
GROUP BY person.person_id;
ただし、これはまだ予定があるperson_idを返すだけで、予定が0の人との戻りは希望しません。
何か提案はありますか?
これには外部結合が必要です(そして、「駆動」テーブルとしてpersonを使用する必要があります)
SELECT person.person_id, COUNT(appointment.person_id) AS "number_of_appointments"
FROM person
LEFT JOIN appointment ON person.person_id = appointment.person_id
GROUP BY person.person_id;
これが機能している理由は、外部(左)結合が、予定のない人に対してNULL
を返すためです。集約関数count()
はNULL
値をカウントしないため、ゼロが取得されます。
外部結合の詳細については、ニースチュートリアルを参照してください。 http://sqlzoo.net/wiki/Using_Null
LEFT JOIN
の代わりにINNER JOIN
を使用する必要があります
SELECT person.person_id, COUNT(appointment.person_id) AS "number_of_appointments"
FROM person
LEFT JOIN appointment ON person.person_id = appointment.person_id
GROUP BY person.person_id;
(カウントで)外部結合を行い、この結果をサブテーブルとして使用すると、期待どおりに0を取得できます(nvl関数のおかげ)
例:
select P.person_id, nvl(A.nb_apptmts, 0) from
(SELECT person.person_id
FROM person) P
LEFT JOIN
(select person_id, count(*) as nb_apptmts
from appointment
group by person_id) A
ON P.person_id = A.person_id
結合を使用して、GROUP BYを使用して結果のカウントを0にします。
単純に「結合」すると、MS SQLで内部結合が行われるため、左または右の結合に進みます。
主キーを含むテーブルがクエリで最初に言及されている場合は、左結合を使用し、そうでない場合は右結合を使用します。
例えば:
select WARDNO,count(WARDCODE) from MAIPADH
right join MSWARDH on MSWARDH.WARDNO= MAIPADH.WARDCODE
group by WARDNO
。
select WARDNO,count(WARDCODE) from MSWARDH
left join MAIPADH on MSWARDH.WARDNO= MAIPADH.WARDCODE group by WARDNO
主キーを持つテーブルからグループ化を行い、実際のエントリ/詳細を持つ別のテーブルからカウントします。
元のクエリの変更をさらに少なくするには、結合をRIGHT
結合に変換できます
SELECT person.person_id, COUNT(appointment.person_id) AS "number_of_appointments"
FROM appointment
RIGHT JOIN person ON person.person_id = appointment.person_id
GROUP BY person.person_id;
これは選択された回答に基づいて構築されますが、外部結合はRIGHT
方向であるため、追加する必要があるのは1つのWordのみであり、変更は少なくなります。 -そこにあることを覚えておいてください。クエリが読みやすくなり、再構築が少なくて済む場合があります。