2017-12-03 4 views
2

サーバーにデータをPOSTするサードパーティのサービスのエンドポイントを構築しています。帯域幅を削減するために、第三者は前のレコードのフィールドからの変更のみを送信します。MySQLテーブルの新しいレコードを作成する方法は、diffの変更のみの前のコピーとして?

ので、テーブルは非常に最初のレコードで、次のようになります想像:

+----+------+------+-------+-------+-------+ 
| id | item | size | color | state | count | 
+----+------+------+-------+-------+-------+ 
| 1 | 0001 | 500 | blue | on | 12 | 
+----+------+------+-------+-------+-------+ 

私に送られるかもしれない次のデータがちょうどitem: 0001, color: green, count: 15だろうと私はテーブルのルックスので、レコードを挿入する必要がありますsizestateフィールドは変更されませんが、次の行までコピーする方法を

+----+------+------+-------+-------+-------+ 
| id | item | size | color | state | count | 
+----+------+------+-------+-------+-------+ 
| 1 | 0001 | 500 | blue | on | 12 | 
| 2 | 0001 | 500 | green | on | 15 | 
+----+------+------+-------+-------+-------+ 

お知らせ:次のように。 (idは単なる自動インクリメントキーです)

さらに、これはitemという識別子ごとに一意です。私はいくつかの異なるitem表は次のようになります記録し得るのであれば:

+----+------+------+-------+-------+-------+ 
| id | item | size | color | state | count | 
+----+------+------+-------+-------+-------+ 
| 1 | 0001 | 500 | blue | on | 12 | 
| 2 | 0001 | 500 | green | on | 15 | 
| 3 | 0002 | 700 | white | off | 42 | 
| 4 | 0001 | 500 | red | off |  9 | 
| 5 | 0003 | 300 | black | on | 66 | 
+----+------+------+-------+-------+-------+ 

それから私は、このメッセージが表示されます。item: 0002, size: 100表は次のようになります。

+----+------+------+-------+-------+-------+ 
| id | item | size | color | state | count | 
+----+------+------+-------+-------+-------+ 
| 1 | 0001 | 500 | blue | on | 12 | 
| 2 | 0001 | 500 | green | on | 15 | 
| 3 | 0002 | 700 | white | off | 42 | 
| 4 | 0001 | 500 | red | off |  9 | 
| 5 | 0003 | 300 | black | on | 66 | 
| 6 | 0002 | 100 | white | off | 42 | 
+----+------+------+-------+-------+-------+ 

私にできる方法はありますこれはMySQLだけでですか?ストアドプロシージャまたは類似のもの?

答えて

0

INSERT INTO ... SELECTここではかなり遠くになるかもしれません。次のINSERT文を考えてみましょう:私はここにあなたのバックエンドテクノロジーは、新しい列の値と一緒に、挿入したいitemを受信されることを前提とし

INSERT INTO yourTable (item, size, color, state, count) 
SELECT '0001', t1.size, 'green', t1.state, 15 
FROM yourTable t1 
INNER JOIN 
(
    SELECT item, MAX(id) AS max_id 
    FROM yourTable 
    GROUP BY item 
) t2 
    ON t1.item = t2.item AND 
     t1.id = t2.max_id 
WHERE t1.item = '0002'; 

。プリペアドステートメントを経由して上記を実行すると、クエリがより次のようになりますことを

注:

INSERT INTO yourTable (item, size, color, state, count) 
SELECT ?, t1.size, ?, t1.state, ? 
FROM yourTable t1 
INNER JOIN 
(
    SELECT item, MAX(id) AS max_id 
    FROM yourTable 
    GROUP BY item 
) t2 
    ON t1.item = t2.item AND 
     t1.id = t2.max_id 
WHERE t1.item = ?; 

このクエリは、潜在的にすべての挿入のために使用することができ、すなわち、あなたはその後、プレースホルダの値を結合するであろう要求。

これに代わる方法は、単一のトランザクション内で完全な選択と、それに続く挿入を実行することです。しかし、1つのクエリでこれを行うことができれば、2つのクエリよりも可能性が高くなります。

+0

私の一意の識別子は上記の例でわかるように 'item'列です。私は前の 'item'レコードの' id'を格納していません。私は 'items'テーブル(これは私が持っている)に追加することができますが、そのIDを調べる必要があるので、それを単一のクエリにする目的を破ることはありませんか? – Bing

+0

@Bing各アイテムの最大IDレコードを探していますか? –

+0

はい、一意の 'item'識別子ごとに最新のレコードを更新します。 – Bing

関連する問題