説明:
特定の日に同じ専門分野の 2 人の異なる医師を訪れた患者のリストを検索する必要があります。
この要件では、Patient
テーブルがメイン テーブルになります。最初にそのテーブルをクエリしましょう。
これで、患者のリストができました。彼らが訪れた医師のリストを取得する必要があります。データをマップする列がないため、Patients テーブルと Doctors テーブルを単純に結合することはできません。Visits を中間テーブルとして使用する必要があります
LEFT OUTER JOIN
患者テーブルと訪問テーブルの間に追加し、pid列で結合します。
患者とその訪問のリストはありますが、今度は医師の情報を取得する必要があります。LEFT OUTER JOIN
そのため、 Visits テーブルと Doctors テーブルの間に別のテーブルを追加し、 did列で結合します。
患者様とご来院の情報を掲載しております。ただし、必要なのは、患者の名前、訪問した医師の専門分野、および訪問した日付だけです。したがって、列を追加p.pname
しd.speciality
、v.date
SELECT句とGROUP BY句にも追加します。これに加えて、すべての訪問数が必要ですが、落とし穴があります。DISTINCT カウントのみが必要です。つまり、訪問したすべての一意の医師のカウントが必要です。したがって、患者が特定の日に同じ医者を 2 回訪れた場合、1 としてカウントする必要がありDISTINCT
ます。また、重要なのは正しい列名を使用することです。この場合、d.didは医師を表します。
必要なデータはすべて揃っていますが、同じ日に 2 人の異なる医師を訪れた患者のみをフィルター処理する必要があります。これを行うには、HAVING 句が役に立ちます。GROUP BY を適用する場合は、HAVING が適切です。同じ COUNT(DISTINCT d.did) を使用して、カウントが2の値のみと一致するかどうかを確認します。出力で結果を確認できます。
提案:
テーブルに挿入されるすべての値に対して INSERT INTO ステートメントを指定する必要はありません。それらを括弧内にグループ化し、 で区切ることができますcommas
。最後のステートメントは で終わる必要がありsemicolon
ます。
クエリはLEFT OUTER JOIN
. この結合を使用して、各患者が一度も医者にかかったことがない場合でも、すべての医者の訪問を調べました。クエリを作成したときの出力を見たかっただけです。これを に変更できます。これINNER JOIN
は、シナリオにより適していると思います。
訪問数を表示したくない場合は、SELECT 句から削除できます。
デモ:
SQL Fiddle でデモを表示するには、ここをクリックしてください。
説明に使用するスクリプト:
SELECT p.pname
, d.speciality
, v.date
, COUNT(DISTINCT d.did) AS visitcount
FROM Patient p
LEFT OUTER JOIN Visits v
ON v.pid = p.pid
LEFT OUTER JOIN Doctors d
ON d.did = v.did
GROUP BY p.pname
, d.speciality
, v.date
HAVING COUNT(DISTINCT d.did) = 2
より適切なスクリプト:
SELECT p.pname
, d.speciality
, v.date
FROM Patient p
INNER JOIN Visits v
ON v.pid = p.pid
INNER JOIN Doctors d
ON d.did = v.did
GROUP BY p.pname
, d.speciality
, v.date
HAVING COUNT(DISTINCT d.did) = 2
出力:
PNAME SPECIALITY DATE VISITCOUNT
--------- ------------ --------- -----------
Loch Ness Assholes 17/9/2012 2
Loch Ness Orthopedist 13/1/2011 2
テーブルを作成し、スクリプトを挿入します。
create table InsuranceCompanies (
cid int,
cname varchar(20),
primary key (cid)
);
create table Patient (
pid int,
pname varchar(20),
age int,
cid int,
gender char,
primary key (pid),
constraint foreign key (cid)
references InsuranceCompanies (cid)
);
create table Doctors (
did int ,
dname varchar(20),
speciality varchar(20),
age int,
cid int,
primary key (did),
constraint foreign key (cid)
references InsuranceCompanies (cid)
);
create table Visits(
vid int,
pid int,
did int,
date varchar(20),
primary key (vid),
constraint foreign key (pid)
references Patient (pid) ,
constraint foreign key (did)
references Doctors (did)
);
INSERT INTO InsuranceCompanies(cid, cname) VALUES
( 1111, 'Harel Inc' ),
( 2222, 'Clalit Inc' );
INSERT INTO Doctors ( did, dname, speciality, age, cid) VALUES
( 100, 'Jhonny Depp', 'Heart', 42, 1111 ),
( 101, 'Tom Tolan', 'Assholes', 62, 1111 ),
( 105, 'Yom Tov', 'Assholes', 52, 1111 ),
( 102, 'Lauren Jaime', 'Throat', 27, 2222 ),
( 103, 'Gomez Flaurence', 'Legs', 37, 2222 ),
( 106, 'David Harpaz', 'Orthopedist', 37, 2222 ),
( 107, 'David Schwimmer', 'Orthopedist', 37, 2222 ),
( 108, 'Sammy Salut', 'Orthopedist', 37, 1111 );
INSERT INTO Patient ( pid, pname, age, cid,gender) VALUES
( 200, 'Jon Gilmour', 25, 2222, 'm' ),
( 206, 'Bon Gilmour', 30, 2222, 'm' ),
( 205, 'Jon Gilmour', 22, 2222, 'm' ),
( 201, 'Bon Jovy', 21, 2222, 'm' ),
( 202, 'Loch Ness', 17, 2222, 'f' ),
( 203, 'Lilach Sonin', 12, 1111, 'f' ),
( 209, 'Lilach Dba', 34, 1111, 'f' ),
( 210, 'Paulina Daf', 32, 1111, 'f' ),
( 204, 'Gerry Jalor', 23, 1111, 'm' ),
( 208, 'Jerrushalem Jalor', 23, 1111, 'm' );
INSERT INTO Visits ( vid, pid, did, date) VALUES
( 300, 204, 100, '12/12/2012' ),
( 301, 204, 101, '12/12/2012' ),
( 302, 204, 101, '02/01/2012' ),
( 303, 202, 101, '17/09/2012' ),
( 311, 202, 105, '17/09/2012' ),
( 304, 203, 102, '12/12/2011' ),
( 312, 202, 106, '13/06/2012' ),
( 314, 202, 107, '13/01/2011' ),
( 313, 202, 108, '13/01/2011' ),
( 305, 204, 102, '10/10/2011' ),
( 306, 201, 100, '12/01/2012' ),
( 316, 204, 108, '18/05/2012' ),
( 307, 202, 100, '12/07/2012' ),
( 315, 203, 108, '12/07/2012' ),
( 310, 204, 103, '10/04/2012' ),
( 308, 203, 102, '12/12/2011' ),
( 309, 200, 101, '12/12/2012' );