如何查找重复内容并使最后一个条目成为主ID?

时间:2015-05-05 17:43:56

标签: mysql

我在 mysql 方面遇到了一些问题,希望您能够帮助我。 :)

此代码用于简化图书馆网站上的搜索结果。一本书可以多次出版,但书的内容保持不变。这就是为什么当我们搜索" Ze Book"或其中一个ISBN。

以下是我的table

id | isbn    | bookname | disabled | alias
1  | A-B-C-D | Ze Book  | 0        |
2  | E-F-G-H | Ze Book  | 0        |
3  | I-J-K-L | Ze Book  | 0        |
4  | M-N-O-P | Bookeee  | 0        |
5  | Q-R-S-T | Bookeee  | 0        |

这就是我想为table做的事情:

id | isbn    | bookname | disabled | alias
1  | A-B-C-D | Ze Book  | 1        |
2  | E-F-G-H | Ze Book  | 1        |
3  | I-J-K-L | Ze Book  | 0        |A-B-C-D, E-F-G-H
4  | M-N-O-P | Bookeee  | 1        |
5  | Q-R-S-T | Bookeee  | 0        |M-N-O-P

我不知道从哪里开始,特别是如果可以直接用mysql完成。

目前,我已设法确定重复的图书名称:

SELECT bookname, COUNT(*) AS number
FROM table
GROUP BY bookname
HAVING COUNT(*) >1
ORDER BY number DESC

任何想法下一步该做什么?

提前感谢,你可能已经注意到了,我还在学习如何编码。 :)

2 个答案:

答案 0 :(得分:1)

以下是我在维护您的表格架构时如何做到这一点:

CREATE TEMPORARY TABLE dupes AS (
   SELECT
      disabled_books.id,
      bookname,
      group_concat(isbn) as isbn_aliases
   FROM books
   INNER JOIN (
      SELECT
         bookname,
         max(id) as keep_id
      FROM books
      GROUP BY bookname
      HAVING count(isbn) > 1) as disabled_books
      ON (books.bookname = disabled_books.bookname
         AND books.id != disabled_books.keep_id)
   GROUP BY bookname)
);


UPDATE books
INNER JOIN dupes USING(bookname)
SET books.disabled = IF(dupes.id = books.id, 0, 1),
books.alias = IF(dupes.id = books.id, dupes.isbn_alias, '');

注意:如果数据库处于活动状态,那么您需要将其更改为存储过程以确保事务完整性。

可能值得考虑放弃别名列并将其移至单独的表以更好地管理这种一对多关系,例如:

CREATE TABLE isbn_aliases (
   isbn CHAR(13),
   isbn_alias CHAR(13),
   PRIMARY KEY (isbn)
) ENGINE=InnoDB DEFAULT CHARSET='utf8';

答案 1 :(得分:1)

你会满意吗?:

CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,isbn VARCHAR(12) NOT NULL
,bookname VARCHAR(12) NOT NULL
);

INSERT INTO my_table VALUES
(1,'A-B-C-D','Ze Book'),
(2,'E-F-G-H','Ze Book'),
(3,'I-J-K-L','Ze Book'),
(4,'M-N-O-P','Bookeee'),
(5,'Q-R-S-T','Bookeee'); 


    SELECT a.*
         , b.aliases  
      FROM my_table a 
      JOIN 
         ( SELECT x.bookname
                , MAX(x.id) max_id
                , GROUP_CONCAT(DISTINCT y.isbn) aliases 
             FROM my_table x 
             JOIN my_table y 
               ON y.bookname = x.bookname 
              AND y.id < x.id 
            GROUP 
               BY x.bookname
         ) b 
        ON b.bookname = a.bookname 
       AND b.max_id = a.id;
+----+---------+----------+-----------------+
| id | isbn    | bookname | aliases         |
+----+---------+----------+-----------------+
|  3 | I-J-K-L | Ze Book  | A-B-C-D,E-F-G-H |
|  5 | Q-R-S-T | Bookeee  | M-N-O-P         |
+----+---------+----------+-----------------+