2016-10-10 8 views
1

次のsqlの構文エラーが1時間ありましたが、回答フォームのpostgresのドキュメントを見つけることができません。他のテーブルを使用しているPostgresの挿入

CREATE TABLE transaction (userid SMALLINT, point INT, timestamp TIMESTAMPTZ); 
CREATE TABLE point (userid SMALLINT PRIMARY KEY, balance1 INT, balance2 INT); 
CREATE TABLE settings (userid SMALLINT, bonus INT); 
INSERT INTO settings VALUES (1, 10); -- sample data 

WITH trans AS (
    INSERT INTO transaction (userid, point, timestamp) 
    VALUES ($1, $2, NOW()) 
    RETURNING * 
) 
INSERT INTO point (userid, balance1) 
SELECT userid, point 
FROM trans -- first time 
ON CONFLICT (userid) DO UPDATE 
    SET balance1=point.balance1 + excluded.balance1, 
     balance2=point.balance2 + excluded.balance1 + settings.bonus 
FROM settings -- tried USING, not work 
WHERE settings.userid=excluded.userid; 

私の質問は、更新中にFROMを使用せずに余分なテーブルを含めるにはどうすればよいですか?私の目標は、すべてを1つのクエリに保つことです。

答えて

0

あなたがしようとしていることは完全にはわかりません。私はそれを理解する方法は、あなたがいる場合にはon conflictキックを行を更新するときsettings.bonusから値を使用しようとしているということです

これはUPDATE部分で共同関連サブクエリを使用して行うことができます。

WITH trans (userid, point, timestamp) AS (
    INSERT INTO transaction (userid, point, timestamp) 
    VALUES (1, 1, NOW()) 
    RETURNING * 
) 
INSERT INTO point (userid, balance1) 
SELECT trans.userid, trans.point 
FROM trans 
ON CONFLICT (userid) DO UPDATE 
    SET balance1 = point.balance1 + excluded.balance1, 
     balance2 = point.balance2 + excluded.balance1 + (select s.bonus 
                 from settings s 
                 where s.userid = excluded.userid) 

注しかし、balance2が原因で最初の挿入時にこのように増加することはないだろうということは、(null + 5がnull)null以降の更新はnullが、ヌル、ヌル利回りを含む任意の式に何かを追加しようとするだろう。

最初に挿入するときは0を挿入するか、更新を行うときにcoalesce()を使用する必要があります。

balance2 = coalesce(point.balance2, 0) + excluded.balance1 + (select ...); 

それは何の行は、そのユーザーのためにsettingsには存在しない可能性があります場合は、あなたが同様にサブクエリの結果coalesce()を適用する必要があります。

... excluded.balance1 + coalesce((select ...), 0) 

また、あなたの質問にexcluded.pointを使用しました。これは間違っています。 excludedは、ターゲット表pointを参照するが、それは、列のポイントを持っていない - あなたはおそらく意味:timestamp:excluded.balance1(つまり、挿入trans.pointが行く先となる列のように)


無関係が、列の恐ろしい名前です。 1つはキーワードだからですが、もっと重要なのは、その列が何のためのものなのかを文書化していないからです。それは "作成時"を意味しますか? "まで有効"? "始まる"? 「時代遅れ」?何か全く違う?

関連する問題