2

親と子のデータベースがあり、子は親に起こったことの一種の実行中のトランスクリプトを保持しているとしましょう:

create table patient (
   fullname text not null,
   admission_number integer primary key
);

create table history (
   note text not null,
   doctor text not null,
   admission_number integer references patient (admission_number)
);

(ほんの一例です。私は医療アプリケーションを行っていません)。

history同じに対して多くのレコードがありますadmission_number:

admission_number      doctor    note
------------------------------------
3456                  Johnson   Took blood pressure
7828                  Johnson   EKG 120, temp 99.2
3456                  Nichols   Drew blood
9001                  Damien    Discharged patient
7828                  Damien    Discharged patient with Rx

それで、私の質問は、patientたとえば、病歴に「血圧」と「除隊」。

現在、私はそのグループに対して を実行selectしており、すべてのメモを で結合し、 で検索を行っています。historyadmission_numbergroup_concat(note)having

select * from history 
  group by admission_number
  having group_concat(note) like '%blood pressure%' 
     and group_concat(note) like '%discharged';

これは機能しますが、特定の精緻化が非常に複雑になります。たとえば、「病歴に「血圧」が含まれていて、ダミアン博士との病歴に「退院」と書かれているすべての患者に質問できるようにしたいと考えています。私の基本的なクエリの上にこのような資格を追加するのは非常に面倒です。

私の基本的なクエリを表現するより良い方法はありますか?

4

3 に答える 3

1

これはあなたの方法に似ていますEXISTSが、サブクエリの計算方法が異なります。これは、テーブルとインデックスがどのように構成されているか、およびクエリの選択性に応じて、高速になる場合とそうでない場合があります。

SELECT *
FROM patient
WHERE admission_number IN (SELECT admission_number
                           FROM history
                           WHERE note LIKE '%blood pressure%')
  AND admission_number IN (SELECT admission_number
                           FROM history
                           WHERE note LIKE '%discharged%'
                             AND doctor = 'Damien')

または、複合サブクエリを使用することもできます(交差点を 1 回計算するとIN、すべてのレコードに対して 2 回実行するよりも高速になる可能性があります)。

SELECT *
FROM patient
WHERE admission_number IN (SELECT admission_number
                           FROM history
                           WHERE note LIKE '%blood pressure%'
                           INTERSECT
                           SELECT admission_number
                           FROM history
                           WHERE note LIKE '%discharged%'
                             AND doctor = 'Damien')
于 2013-03-07T08:13:25.490 に答える
1

操作を使用しませんJOINか?

たとえば、患者テーブルには次のデータが含まれているとします。

INSERT INTO patient VALUES('Bob', 3456);
INSERT INTO patient VALUES('Mary', 7828);
INSERT INTO patient VALUES('Lucy', 9001);

クエリの実行:

SELECT DISTINCT p.fullname, p.admission_number FROM patient p
INNER JOIN history h ON p.admission_number = h.admission_number
WHERE note LIKE '%blood pressure%' OR note LIKE '%Discharged%';

あなたを取得します:

fullname = Bob
admission_number = 3456

fullname = Lucy
admission_number = 9001

fullname = Mary
admission_number = 7828

そして、次のクエリを実行します。

SELECT DISTINCT p.fullname, p.admission_number FROM patient p
INNER JOIN history h ON p.admission_number = h.admission_number
WHERE note LIKE '%blood pressure%';

あなたを取得します:

fullname = Bob
admission_number = 3456
于 2013-03-06T21:34:29.223 に答える
1

私は何かを持っています -EXISTSこれらを構築するために使用するのは少しきれいです:

select * from patients where 
    exists ( 
      select 1 from history where
        history.admission_number == patients.admission_number
        AND
        history.note LIKE '%blood pressure%'
    )
    AND
    exists (
        select 1 from history where
        history.admission_number == patients.admission_number
        AND 
        history.note LIKE '%discharged%'
        AND
        history.doctor == 'Damien'
    );

これで、非常にきめ細かい述語を作成できるようになりました。

于 2013-03-06T22:30:25.003 に答える