マルチコラムサブQueriesを使用して、行のポストグレスバルクアップデート
-
29-10-2019 - |
質問
親テーブルの6フィールドの子テーブルからの要約値(カウント、最小、最大)でテーブル(親テーブル)のすべての行を更新する必要があります
tab1 (parent table)
-------------------
tab1_ID
tab1_low
tab1_high
tab2_ref_count
tab2_ref_low
tab2_ref_high
tab3_ref_count
tab3_ref_low
tab3_ref_high
STUS_CD
tab2 (link table for tab1 to tab1)
----------------------------------
tab1_ID
tab1_ref_ID
tab3 (link table for tab1 to tab4)
----------------------------------
tab1_ID
tab4_ref_ID
tab4
-----
tab4_ID
tab4_low
tab4_high
Tab2とTab3のカウントをTab1にロールアップするには、以下が私が試みているクエリです -
UPDATE tab1
SET (tab2_ref_count, tab2_ref_low, tab2_ref_high) =
(SELECT COUNT(t1.tab1_ID), MIN(t1.tab1_low), MAX(t1.tab1_high)
FROM tab2 t2 JOIN tab1 t1 ON (t2.tab1_ref_ID = t1.tab1_ID)
WHERE tab1.tab1_ID = t2.tab1_ID),
(tab3_ref_count, tab3_ref_low, tab3_ref_high) =
(SELECT COUNT(t4.tab4_ID), MIN(t4.tab4_low), MAX(t4.tab4_high)
FROM tab3 t3 JOIN tab4 t4 ON (t3.tab4_ref_ID = t4.tab4_ID)
WHERE tab1.tab1_ID = t3.tab1_ID)
WHERE STUS_CD IN ('01','02')
しかし、どうやらそれは機能していません。ヒントはありますか?
解決
このように機能する可能性があります:
UPDATE tab1 t1
SET tab2_ref_count = t2.ct
, tab2_ref_low = t2.low
, tab2_ref_high = t2.high
, tab3_ref_count = t3.ct
, tab3_ref_low = t3.low
, tab3_ref_high = t3.high
FROM (
SELECT t2.tab1_id
, count(*) AS ct
, min(t1.tab1_low) AS low
, max(t1.tab1_high) AS high
FROM tab2 t2
JOIN tab1 t1 ON t1.tab1_id = t2.tab1_ref_id
GROUP BY 1
) t2
JOIN (
SELECT t3.tab1_id
, count(*) AS ct
, min(t4.tab1_low) AS low
, max(t4.tab1_high) AS high
FROM tab3 t3
JOIN tab4 t4 ON t4.tab4_id = t3.tab4_ref_id
GROUP BY 1
) t3 USING (tab1_id)
WHERE stus_cd IN ('01','02')
AND t1.tab1_id = t2.tab1_id;
-- AND t1.tab1_id = COALESCE(t2.tab1_id, t3.tab1_id); .. for FULL OUTER JOIN
主要なポイント:
私が使う
count(*)
それ以外のcount(t4.tab1_id)
. 。ここでは同じ結果が保証されていますが、よりシンプルで速いです。クエリは、行があることを前提としています
tab3
すべてのためのtab1_id
それがありますtab2
, 、 それも。そうでない場合は、JOIN
タイプにLEFT JOIN
またFULL OUTER JOIN
. 。この場合の最終Where句で提供された代替案を使用します。このクエリは行を更新しません
tab1
まったく、関係していない場合はどちらにもありますtab2
またtab3
.
他のヒント
PostgreSQLは、更新ステートメントでタプルの定義をサポートしていません(しかし、計画されていると思います)
このようなものを使用できます(テストされていません):
UPDATE tab1
SET tab2_ref_count = tt1.tab1_id_count,
tab2_ref_low = tt1.tab1_low_min,
tab2_ref_high = tt1.tab1_high_max
FROM (
SELECT COUNT(t1.tab1_ID) as tab1_id_count,
MIN(t1.tab1_low) as tab1_low_min,
MAX(t1.tab1_high) as tab1_high_max
FROM tab2 t2
JOIN tab1 t1 ON (t2.tab1_ref_ID = t1.tab1_ID)
WHERE tab1.tab1_ID = t2.tab1_ID
) tt1
....
WHERE STUS_CD IN ('01','02')
(どこ ...
例の2番目のサブセレクトの2番目の派生テーブルを示します)
所属していません StackOverflow