2つのテーブルがあります。
CREATE TABLE one (
id int4 primary key,
p_id int4,
k_id int4,
c_id int4
);
CREATE TABLE two(
id int4 primary key,
p_id int4,
k_id int4,
t_id int4,
pos int4
);
テーブルone
:は結合テーブルです。このレポートでは、c_id
と行数を制限するためにのみ使用しています。
テーブルtwo
:には私のデータが含まれ、p_id
、k_id
、t_id
には多くのpos
を含めることができるため、それらをグループ化し、min()
を使用して最小pos
を取得します。 k_id
とp_id
のすべてのデータを取得するいくつかの方法を試しました これが方法です (この解決策では、pos
で注文できませんでした) (フィドルを参照) :
SELECT
o.p_id,
o.k_id,
min(t.pos) as t_pos,
min(t1.pos) as t1_pos
FROM one o
LEFT JOIN two t ON t.p_id = o.p_id
AND t.k_id = o.k_id
AND t.t_id = 1
LEFT JOIN two t1 ON t1.p_id = o.p_id
AND t1.k_id = o.k_id
AND t1.t_id = 2
WHERE o.p_id = 1 AND o.c_id = 1
GROUP BY 1, 2
LIMIT 1
このソリューションは2〜3倍遅くなります 他の投稿の@Erwin Brandstetterのソリューション ですが、t_pos
、t1_pos
の並べ替えが可能で、たとえばtype_id = 1
とpos = 1
のすべてのデータも取得できます。
同じ出力を達成して速度を向上させ、データ(t_pos
およびt1_pos
列)をソートできるより良い方法はありますか?
これがどれだけ効果的か試してください
両方のt_idについて、テーブル2の1つの内部結合に左結合を変換しました。そして、minの計算では、caseステートメントを使用して、値t_idに基づいて2つの列に分割します。ここで保存するのは、テーブルを2回スキャンし、左結合と比較して内部結合です。
SELECT
o.p_id,
o.k_id,
MIN(case when t.t_id = 1 then t.pos else null end) AS t_pos,
MIN(case when t.t_id = 2 then t.pos else null end) AS t1_pos
FROM
one o
INNER JOIN two T ON t.p_id = o.p_id
AND t.k_id = o.k_id
AND t.t_id =any ( 1,2)
WHERE
o.p_id = 1
AND o.c_id = 1
GROUP BY
1,
2
LIMIT 1