Postgresql
避免多次加入同一個表
我有兩張桌子:
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 );
Table
one
: 是一個連接表,我在這個報告中使用它只是因為c_id
and 來限制行數。表
two
:包含我的數據 ap_id
,k_id
並且t_id
可以有很多pos
,所以我將它們分組並使用min()
, 來獲取 minpos
。我已經嘗試了一些方法來獲取我的所有數據,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
此解決方案比另一篇文章中@Erwin Brandstetter 的解決方案慢 2-3 倍,但排序是可能的
t_pos
,並且還可以在例如t1_pos
哪裡獲取所有數據。type_id = 1``pos = 1
有沒有更好的方法來實現相同的輸出並提高速度並能夠對我的數據(
t_pos
和t1_pos
列)進行排序?
試試這對你有多好
將兩個 t_id 的表二的左連接轉換為一個內連接。在計算最小值時,使用 case 語句根據值 t_id 拆分為兩列。我們在這裡保存的是兩次掃描表和與左連接相比的內連接
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