以下に示すように、新しいレコードと更新されたレコードをすべて取得するには結合する必要がある 2 つの関連テーブルがあります。これらは、単純化されたテーブル構造を持つ代表的な例です。
最初のテーブルは項目のテーブルです。たとえば、すべての既存のメモと「新しい」メモおよび既存のメモの更新を含む「メモ」です。
2 番目のテーブルには、メモに対する保留中の変更/更新の詳細が含まれています。たとえば、メモが変更されている場合、その行は変更されて複製され、元のメモの ID、更新を含む行の ID、および更新を行ったユーザーを含む行が pendingUpdates テーブルに追加されます。新しいメモが追加された場合、元の ID と変更された ID が同じ行を参照することを除いて、ワークフローは似ています。
Notes:
+----+---------------------+----------------------------+
| id | title | text |
+----+---------------------+----------------------------+
| 1 | this is a test note | blah blah blah |
| 2 | note 2 | sdfsadfasdf |
| 3 | note 3 | jklhjklhjklhjk |
| 4 | note 3 | This is an update to note3 |
| 5 | note 3 | another update |
| 6 | note 4 | new note |
+----+---------------------+----------------------------+
pendingUpdates:
+----+------------+---------+------+
| id | originalId | cloneId | user |
+----+------------+---------+------+
| 1 | 3 | 4 | 1 |
| 2 | 3 | 5 | 1 |
| 3 | 6 | 6 | 2 |
+----+------------+---------+------+
私がやりたいことは、SELECT を実行してすべてのメモを取得し、そのメモに変更 (更新のリストを含む) と新しいメモがあるかどうかを含めることです。
したがって、上記の例では、行 1、2、3、および 6 が返されます。行 3 には、4、5 が更新としてリストされます。
望ましい結果の例:
+----+------------+-------------+------+--------+---------------------+
| id | hasChanges | isNewRecord | p_id | clones | title |
+----+------------+-------------+------+--------+---------------------+
| 1 | no | no | NULL | NULL | this is a test note |
| 2 | no | no | NULL | NULL | note 2 |
| 3 | yes | no | 1 | 4,5 | note 3 |
| 6 | yes | yes | 3 | 6 | note 4 |
+----+------------+-------------+------+--------+---------------------+
さまざまなクエリの組み合わせを試しましたが、必要なものを正確に取得していません。これは私が持っているもので、かなり近いものですが、結果セットに行4と5が含まれていますが、これは望ましくありません。
SELECT
o.id,
if(o.id = p.originalId, 'yes', 'no') AS hasChanges,
if(p.cloneId = p.originalId,
'yes',
'no') AS isNewRecord,
p.id AS p_id,
group_concat(p.cloneId
separator ',') AS clones,
o.title
FROM
`notes` AS o
LEFT JOIN
`pendingUpdates` AS p ON (o.id = p.originalId)
group by id;
これは次を返します:
+----+------------+-------------+------+--------+---------------------+
| id | hasChanges | isNewRecord | p_id | clones | title |
+----+------------+-------------+------+--------+---------------------+
| 1 | no | no | NULL | NULL | this is a test note |
| 2 | no | no | NULL | NULL | note 2 |
| 3 | yes | no | 1 | 4,5 | note 3 |
->| 4 | no | no | NULL | NULL | note 3 |
->| 5 | no | no | NULL | NULL | note 3 |
| 6 | yes | yes | 3 | 6 | note 4 |
+----+------------+-------------+------+--------+---------------------+
解決:
これが私が最終的に使用した最終的な解決策です。これは fthiella のものに最も似ています。
これを手伝ってくれたすべての人にもう一度感謝します。
SELECT
m.id,
if(m.max_pending IS NOT NULL, 'yes', 'no') hasChanges,
if(m.id = pendingUpdates.cloneId, 'yes', 'no') isNew,
m.clones,
m.pendingIds,
m.title
FROM (SELECT
Notes.id,
MAX(pendingUpdates.id) max_pending,
GROUP_CONCAT(pendingUpdates.id) pendingIds,
GROUP_CONCAT(pendingUpdates.cloneId) clones,
MAX(title) title
FROM Notes
LEFT JOIN pendingUpdates ON Notes.id = pendingUpdates.originalId
GROUP BY Notes.id
) m
LEFT JOIN pendingUpdates ON m.max_pending = pendingUpdates.id
WHERE
m.id NOT IN (SELECT
cloneId
FROM pendingUpdates
WHERE cloneId NOT IN (SELECT
originalId
FROM pendingUpdates)
)
order by id;