特に、次の2つのテーブルを含むデータベースがあります。
classes
は、クラススケジュールのクラスごとに1つの行を持つ単純なテーブルです。
sessions
は、各クラスが出会う日時を特徴付けるテーブルであり、各行は次のような概念を表現できます。
"火曜日|1月22日-3月5日|6-9pm"
"火曜日と木曜日|1月22日-3月7日|6-9pm"
"月曜日-木曜日|1月21-24日|3-6pm"
"土曜日|3月9日|9am-午後4時"
等々。
sessions
の各行には少なくとも1つの行が存在することが保証されてclasses
おり、特定のクラスでは、2つ以上の関連するセッション行が存在する場合があります。
現在、次のように、2つの異なるクエリを使用して、特定の基準セットに一致するクラスのクラスおよびセッション情報を取得しています。
select c.class_id, c.title, c.instructor, c.num_seats, c.price
from classes c
join classes_by_department cbd
on (cbd.class_id = c.class_id)
join /* several other tables */
on /* several other join conditions */
where cbd.department_id = '{$dept_id}'
and /* several other qualifying conditions */
;
この:
select s.class_id, s.start_date, s.end_date, s.day_bits, s.start_time, s.end_time
from sessions s
join classes c
on (c.class_id = s.class_id)
join classes_by_department cbd
on (cbd.class_id = s.class_id)
join /* the same other tables */
on /* the same other join conditions */
where cbd.department_id = '{$dept_id}'
and /* the same other qualifying conditions */
;
これは正常に機能し、少なくとも現在のアプリケーションでは、テーブルが十分に大きくなく、トラフィックが十分に多くないため、2つのクエリが問題になります。それにもかかわらず、それは少し無駄だと思います。最初のクエリですでに行われた作業を活用して、2番目のクエリを実行する方法がないのではないかと思います(同じクエリを2回実行することになります。別の列を選択するだけです)。
もちろん、1つのクエリ(2番目のクエリ)から関連するすべての列を選択できることはわかっていますclasses
がsessions
、現在のアプローチでは、最初のクエリが、修飾クラスごとに1行だけを配信するという事実が気に入っています。クラスにはセッションレコードがあるため、多くの行。クエリをマージした場合、クエリ結果を処理する既存のロジックを再構築する必要があります。(ええ、私は知っています、waah ...)
私が思いついた解決策の1つは、最初のクエリによって返されたすべてのをベクトルに収集しclass_id
(とにかくそれらの結果を反復処理する必要があるため)、そのベクトルの内容を句の値リストの内容としてフォーマットすることです。 IN
、2番目のクエリが単純に次のようになるようにします。
select s.class_id, s.start_date, s.end_date, s.day_bits, s.start_time, s.end_time
from sessions s
where s.class_id in (/* value-list */);
巨大なSQLクエリは大したことではないことを理解しているので、このようなソリューションのスケーラビリティについてはあまり心配していません。さらに、で定義されたインデックスを利用できますsessions.class_id
。
しかし...まあ...SQLチョップを改善しようとしている人にとってはあまり満足のいくものではありません。これはかなり初歩的なことです。それはエレガントではなく、あまり「SQLっぽい」ものではなく、Pythonicという用語に相当するSQLが何であれ、そうではありません。
誰かがもっと適切なことを提案できますか?