「ゼロ」/「0」の結果をCOUNT集計に含める方法は?


112

少し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の人の戻りである私が欲しいものは返しません!

何か提案がありますか?


1
ゼロを取得したい場合| 単一のテーブルでは結果として0。私はvm_tool_licensesテーブルを持っていますが、クエリは以下のようなものです。selectvm_tool_id、count(vm_tool_license_active)from vm_tool_licenses group by vm_tool_license_active、vm_tool_id having vm_tool_license_active = false`
Narendra

回答:


101

このための外部結合が必要です(そして、「駆動」テーブルとして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


しかし、予定の一部のフィールドが(テーブル定義で)NULLでない場合はどうなりますか?
Lior Yehezkely

@LiorYehezkely:「列の一部」は関係ありません。count()は結合列を使用します。それがnullでない場合、カウントする予定があります
a_horse_with_no_name

21

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;

1
GROUP BYは、テーブルがクエリに含まれていないため、元の質問ではタイプミスのように見えます。
Joachim Isaksson 2013

7

(カウントを使用して)外部結合を行い、この結果をサブテーブルとして使用すると、期待どおりに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

5

GROUP BYを使用して結果の0カウントを取得するには、結合を使用します。

単純に 'join'はMS SQLで内部結合を行うので、左または右結合に移動します。

主キーを含むテーブルがQUERYで最初に言及されている場合は、LEFT結合を使用し、それ以外はRIGHT結合を使用します。

例えば:

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

主キーを持つテーブルからグループ化し、実際のエントリ/詳細を持つ別のテーブルからカウントします。


2

元のクエリの変更をさらに少なくするには、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語のみで、変更は少なくなります。-そこにあり、クエリを読みやすくし、再構築の必要性を少なくできることを覚えておいてください。


0

LEFT JOINの問題は、アポイントメントがない場合でも、nullのある1行を返し、COUNTで集計すると1になり、実際にアポイントメントが1つもない場合でも、そのアポイントメントが1つあるように見えることです。これは正しい結果を与えると思います:

SELECT person.person_id,
(SELECT COUNT(*) FROM appointment WHERE person.person_id = appointment.person_id) AS 'Appointments'
FROM person;

私はこれと同じ解決策を投稿するつもりでした、とても簡単です。
ジョエル
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.