我用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,其他修订版本均为NULL)。我现在想要的是获得每个类别,这些类别都有新的重新组合(注意,一旦提交了修订版,它就不能立即设置为当前。这是由例如主持人完成的)。我的问题现在也是每个类别,它只有一个版本,当前IS NULL
因此预期结果将是:
-------------
| 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
答案 0 :(得分:4)
我制作了一个SQL Fiddle Demo,它具有适合您需求的不同表格结构
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 );