1

mysql (および php) でバージョン管理を実装しました。

次のようになります。

categories
-------------
| id | name |
|----|-------
| 1  | a
| 2  | b
| 3  | c
| 4  | d
-------------


revisions
----------------------
| id | cid | current |
|----|-----|----------
| 1  |  1  | 1       |
| 2  |  1  | NULL    |
| 3  |  2  | NULL    |
| 4  |  3  | 1       |
| 5  |  4  | NULL    |
| 6  |  4  | 1       |
----------------------

各カテゴリには複数のリビジョンが割り当てられています。"current" が 1 に設定されている場合、リビジョンが設定されます (カテゴリごとに 1 つのリビジョンのみが 1 になり、その他はすべて NULL になります)。私が今欲しいのは、新しいリビジョンを持つすべてのカテゴリを取得することです(リビジョンが送信されると、すぐに最新に設定されないことに注意してください。これは、モデレーターなどによって行われます)。私の問題は、現在のIS NULLのリビジョンが1つしかない各カテゴリも取得するようになりました

したがって、期待される結果は次のようになります。

-------------
| category.id
|------------
| 1     
| 2     
-------------

ではごきげんよう

編集://

私の現在の解決策は次のとおりです。

SELECT categories.* FROM categories
JOIN revisions as t1 ON
(
t1.cid = categories.id
t1.current IS NULL
)
JOIN revisions as t2 ON
(
t2.id != t1.id
t2.current IS NOT NULL
t2.cid = categories.id
)
WHERE t1.id > t2.id
4

1 に答える 1

4

私はあなたのニーズに合う異なるテーブル構造でSQLフィドルデモを作りました

CREATE TABLE `categories` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(1) NOT NULL DEFAULT '',
  `revision_id` int(11) unsigned DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO categories
    (`id`, `name`, `revision_id`)
VALUES
    (1, 'a', 1),
    (2, 'b', null),
    (3, 'c', 4),
    (4, 'd', 6),
    (5, 'e', 7),
    (6, 'f', 9)
;

CREATE TABLE `revisions` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `category_id` int(11) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;   

INSERT INTO revisions
    (`id`, `category_id`)
VALUES
    (1, 1),
    (2, 1),
    (3, 2),
    (4, 3),
    (5, 4),
    (6, 4),
    (7, 5),
    (8, 6),
    (9, 6)
;

外部キー関係

ALTER TABLE `categories` 
  ADD CONSTRAINT `fk_cat_rev` 
  FOREIGN KEY (`revision_id`) 
  REFERENCES `revisions` (`id`) ON UPDATE CASCADE ON DELETE SET NULL;

ALTER TABLE `revisions` 
  ADD CONSTRAINT `fk_rev_cat` 
  FOREIGN KEY (`category_id`) 
  REFERENCES `categories` (`id`) ON UPDATE CASCADE ON DELETE CASCADE;

DELETEの関係を確認してください

DELETE FROM revisions WHERE id = 7;
DELETE FROM categories WHERE id = 6;

SELECT 
  cid 
FROM (
  SELECT 
    c.id cid, 
    MAX( r.id ) mrid, 
    c.revision_id rid
  FROM 
    categories c
  JOIN 
    revisions r ON r.category_id = c.id
  GROUP BY 
    c.id ) tmp
WHERE 
  COALESCE( mrid, 0 ) <> COALESCE( rid, 0 );

SQLフィドルデモ

于 2012-12-20T13:41:05.873 に答える