合并SQL记录

时间:2011-04-05 00:39:09

标签: php mysql merge

嘿,我不确定这是不是这个问题的合适的地方,但是我的剧本很麻烦。我正在尝试与PHP进行一些数据库合并,这是一次性合并。我正在做的是抓住一本书的所有独特标题的列表,然后通过这些标题预先找到具有该标题的书籍并按类型分组,然后通过该结果预先找到具有该独特标题和类型的书籍,重复该过程版权和出版商。主要问题是这需要很长时间才能使mysql服务器超时。是否有更好的方法可以使用SQL?

合并的一个例子是:

INSERT INTO books (1, 'Some Book', 'Penguin Publishing', '2005', 1);
INSERT INTO books (2, 'Some Book', 'Penguin Publishing', '2005', 1);
INSERT INTO books (3, 'Some Book 2', 'Penguin Publishing', '2005', 1);
INSERT INTO books (4, 'Some Book 2', 'Lion Publishing', '2005', 1);
INSERT INTO books (5, 'Some Book 2', 'Penguin Publishing', '2005', 2);
INSERT INTO books (6, 'Some Book 2', 'Penguin Publishing', '2005', 2);
INSERT INTO books (7, 'Somebody', 'Lion Publishing', '2005', 1);
INSERT INTO books (8, 'Somebody', 'Lion Publishing', '2007', 1);
INSERT INTO books (9, 'Somebody', 'Penguin Publishing', '2005', 1);

Id 1& 2应该加入,因为它们有1)相同的标题2)相同的material_type_id 3)相同的版权和4)相同的出版商。

有没有办法用PURE SQL或者使用次要的PHP来实现这个目的?

这是我的数据结构:

CREATE TABLE books (
  id int(11) NOT NULL AUTO_INCREMENT,
  title varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  publisher varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  copyright varchar(255) COLLATE utf8_unicode_ci DEFAULT NULL,
  material_type_id int(11) DEFAULT NULL
  PRIMARY KEY (id),
  FULLTEXT KEY title (title)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

修改的 我想我忘了提到一些非常重要的东西。我不能只使用GROUP查询,因为我需要使用id。我有另一个名为'Items'的表,其中包含字段book_id。如果我只是对记录进行分组,我最终会得到孤立的项目。我需要的是一种分解订单查询的方法,所以我最终会得到这样的结果:

id | title | publisher | copyright | material_type_id
-----------------------------------------------------
1  'Some Book' 'Penguin Publishing' '2005' 1
2  'Some Book' 'Penguin Publishing' '2005' 1
-----------------------------------------------------
5  'Some Book 2' 'Penguin Publishing' '2005' 2
6  'Some Book 2' 'Penguin Publishing' '2005' 2
-----------------------------------------------------
3  'Some Book 2' 'Penguin Publishing' '2005' 1
-----------------------------------------------------

因为我可以在第一组上运行这样的查询:

UPDATE items SET book_id = 1 WHERE book_id IN (1, 2)

我希望这是有道理的。我真的很难解释。感谢您的帮助和耐心。

1 个答案:

答案 0 :(得分:1)

此查询保留给定重复规则的书籍的所有副本(使用最小ID)。

DELETE FROM A
using books A
join (select title,publisher,material_type_id,copyright, MIN(id) keep
    from books
    group by title,publisher,material_type_id,copyright
    having count(*) > 1) B
    on A.title=B.title
       and A.publisher=B.publisher
       and A.material_type_id=B.material_type_id
       and A.copyright=B.copyright
       and A.id <> B.keep;

之前运行上述内容,首先移动项目记录(未经过正式测试)

UPDATE items
join books A on A.id = items.book_id
join (select title,publisher,material_type_id,copyright, MIN(id) keep
    from books
    group by title,publisher,material_type_id,copyright
    having count(*) > 1) B
    on A.title=B.title
       and A.publisher=B.publisher
       and A.material_type_id=B.material_type_id
       and A.copyright=B.copyright
       and A.id <> B.keep
set items.book_id = B.keep