3

次のようなデータベースのテーブル B を更新しようとしています。

Table A:
id, amount, date, b_id
1,200,6/31/2012,1
2,300,6/31/2012,1
3,400,6/29/2012,2
4,200,6/31/2012,1
5,200,6/31/2012,2
6,200,6/31/2012,1
7,200,6/31/2012,2
8,200,6/31/2012,2

Table B:
id, b_amount, b_date
1,0,0
2,0,0
3,0,0

このクエリを使用すると、必要なすべてのデータを 1 回の選択で取得できます。

SELECT A.*,B.* FROM A LEFT JOIN B ON B.id=A.b_id WHERE A.b_id>0 GROUP BY B.id

id, amount, date, b_id, id, b_amount, b_date
1,200,6/31/2012,1,1,0,0
3,400,6/29/2012,1,1,0,0

ここで、選択した列の金額を b_mount に、日付を b_date にコピーしたいだけです

b_amount=amount, b_date=date

その結果

id, amount, date, b_id, id, b_amount, b_date
1,200,6/31/2012,1,1,200,6/31/2012
3,400,6/29/2012,1,1,400,6/29/2012

COALESCE() を試しましたが成功しませんでした。経験豊富な誰かがこれに対する解決策を持っていますか?

解決:

以下の回答のおかげで、私はこれを思い付くことができました。これはおそらく最も効率的な方法ではありませんが、1 回だけの更新であれば問題ありません。これにより、各グループの最初の対応するエントリが挿入されます。

REPLACE INTO A SELECT id, amount, date FROM 
(SELECT  A.id, A.amount, B.id as Bid FROM A INNER JOIN B ON (B.id=A.B_id)
ORDER BY A.id DESC) 
GROUP BY Bid;
4

2 に答える 2

1

あなたが探しているのは、UPDATE クエリ内の JOIN のようです。mySQLでは、使用します

UPDATE B INNER JOIN A ON B.id=A.b_id SET B.amount=A.amount, B.date=A.date;

しかし、このおそらく関連する質問が指摘しているように、これはsqliteではサポートされていません。ただし、REPLACE を使用した回避策があります。

REPLACE INTO B 
SELECT B.id, A.amount, A.date FROM A 
LEFT JOIN B ON B.id=A.b_id 
WHERE A.b_id>0 GROUP BY B.id;

クエリは、状態を維持する必要があるすべての列に対してテーブル B の値を入力し、コピーされた値に対してテーブル A の値を入力するだけです。SELECT ステートメントの列の順序がテーブル B の列の順序と一致していることを確認してください。すべての列が記載されていないと、これらのフィールドのデータが失われます。これは、テーブル B の将来の変更に対しておそらく危険です。そのため、テーブル B を変更するときは、このクエリの列の順序/存在を変更することに注意してください。

あなたがそれを求めていないので、少し話題から外れた何か:A.b_id明らかに B.id への外部キーです。外部キーの値0を使用して、B に対応するエントリがないことを表現しているようです (SELECT をWHERE A.b_id>0使用したものから推測されます) null。thenを使用している場合はINNER JOIN、代わりにLEFT JOINWHERE 句を完全に削除できます。次に、DBS は満たされていないすべての関係を整理します。

于 2012-06-05T18:21:49.000 に答える
0

警告 一部の RDBMS は、上記のように 2 行を返します。他のものは、行のデカルト積、つまり A 行と B 行の積を返します。

トリッキーな方法の 1 つは、SQL を生成してから実行することです。

SELECT "update B set b.b_amount = ", a.amount, ", b.b_date = ", a.date, 
" where b.id = ", a.b_id
FROM A LEFT JOIN B ON B.id=A.b_id WHERE A.b_id>0 GROUP BY B.id

ここで、バッチ ターミネータを追加して、この SQL を実行します。クエリの結果は次のようになります

 update B set b.b_amount = 200, b.b_date = 6/31/2012 where b.id = 1 

 update B set b.b_amount = 400, b.b_date = 6/29/2012 where b.id = 3 

注: 一部の RDBMS では、日付の処理が異なります。引用符が必要なものもあります。

于 2012-06-04T22:02:59.227 に答える