根据每个组中的一列删除重复项

时间:2017-04-11 13:21:35

标签: mysql

我的db看起来像这样:RoomRegistrations 1 <--> 1 Students 1 <--> 1 BorrowedBooks

RoomRegistrations:
RoomId | Id
1      | 92051048757
1      | 92342103461
2      | 92430234763

Students:
Id          | Name  | Surname
92051048757 | Tom   | Jones
92342103461 | Andrew| Brown
92430234763 | Brad  | Morrison

BorrowedBooks:
BookId | Id          | Title
1      | 92051048757 | Abcdefg
2      | 92342103461 | Abcdefg
3      | 92430234763 | hijklmn

基本上每个学生都可以借到他们想要的任意数量的书籍,但有一个限制。任何房间都不能有重复的书籍,所以如果学生A借用Abcd而学生B借用Abcd并且他们都住在1号房间,那么我只想选择一个副本并忽略该房间的重复。

对我来说,有很多事情要发生,我不知道如何解决这个问题。我知道我需要按RoomId对学生进行分组,所以我得到了小组:

SELECT RoomRegistrations.RoomId, Students.Name, Students.Surname, BorrowedBooks.Title
FROM (RoomRegistrations INNER JOIN Students ON RoomRegistrations.Id = Students.Id) 
INNER JOIN BorrowedBooks 
ON Students.Id = BorrowedBooks.Id
GROUP BY RoomRegistrations.RoomId, Students.Name, Students.Surname, BorrowedBooks.Title;

现在我只需要将每个组过滤为Title一列,这样我就可以删除字段Title中每个组中的重复项,这就是我被困住的地方。

4 个答案:

答案 0 :(得分:0)

您可以使用以下查询为每个现有RoomId - BookId选择一个学生ID

SELECT rr.RoomId, bb.BookId, MIN(s.Id)
FROM RoomRegistrations AS rr
JOIN Students AS s ON rr.Id = s.Id
JOIN BorrowedBooks AS bb ON s.Id = bb.Id
GROUP By rr.RoomId, bb.BookId;

查询只会选择具有最小Id值的学生。

答案 1 :(得分:0)

如果您对NameSurname之间只有一个感到满意,那么只需使用max()到该列就可以实现这一目标

SELECT  t1.RoomId, max(t2.Surname), t3.Title
FROM    RoomRegistrations t1
JOIN    Students t2 ON t1.Id = t2.Id) 
JOIN    BorrowedBooks t3
ON      t2.Id = t3.Id
GROUP BY t1.RoomId, t3.Title

如果您希望这两项都不起作用,因为max(Name)max(Surname)可能属于不同的学生。在这种情况下,您可以添加一个join一个表格,该表格可以为您提供第一个Surname(或Name,无论您喜欢什么)

SELECT  t1.RoomId, t2.Name, t2.Surname, t3.Title
FROM    RoomRegistrations t1
JOIN    Students t2 ON t1.Id = t2.Id) 
JOIN    BorrowedBooks t3
ON      t2.Id = t3.Id
JOIN    (
            select  t1.RoomId, t3.Title, max(t2.Surname) Surname
            FROM    RoomRegistrations t1
            JOIN    Students t2 ON t1.Id = t2.Id) 
            JOIN    BorrowedBooks t3
            ON      t2.Id = t3.Id
            GROUP BY t1.RoomId, t3.Title
        ) t4
ON      t1.RoomId = t4.RoomId and t3.Title = t4.Title and t2.Surname = t4.Surname
GROUP BY t1.RoomId, t2.Name, t2.Surname, t3.Title

答案 2 :(得分:0)

你可以试试这个:

CREATE TABLE RR (ROOMID int, ID BIGINT);
INSERT INTO RR VALUES (1,92051048757);
INSERT INTO RR VALUES (1,92342103461);

CREATE TABLE S (ID BIGINT, NAME VARCHAR(20), SURNAME VARCHAR(20));
INSERT INTO S VALUES (92051048757 ,'Tom','Jones');
INSERT INTO S VALUES (92342103461  ,'And','Brown');
INSERT INTO S VALUES (92430234763  ,'Brad','Morr');

 CREATE TABLE BB (BOOKID INT, ID BIGINT, TITLE VARCHAR(20));
INSERT INTO BB VALUES (1, 92051048757  ,'abcd');
INSERT INTO BB VALUES (2, 92342103461   ,'abcd');
INSERT INTO BB VALUES (3, 92430234763   ,'hjik');

SELECT X.* , S.NAME, S.SURNAME
FROM (
    SELECT RR.RoomId,  BB.Title, MIN(RR.ID) AS STUD_ID 
    FROM RR 
    INNER JOIN S ON RR.Id = S.Id
    INNER JOIN BB ON S.Id = BB.Id
    GROUP BY RR.RoomId, BB.Title
    ) X
INNER JOIN S ON X.STUD_ID=S.ID
;

输出:

    RoomId  Title   STUD_ID NAME    SURNAME
1   1   abcd    92051048757 Tom Jones

答案 3 :(得分:0)

我不能将此作为评论发布,因为我的声誉不够高,但我想补充Stefano所说的,你可以使用concat声明选择姓名:

mysql> select rooms.rID, 
       max(concat(students.name," ",students.surname)) as name, 
       books.title from ( rooms join students on rooms.sID = students.sID ) 
       join books on books.sID = students.sID 
       group by rooms.rID,books.title;

+-----+---------------+---------+
| rID | name          | title   |
+-----+---------------+---------+
|   1 | Tom Jones     | Abcdefg |
|   2 | Brad Morrison | Hijklm  |
+-----+---------------+---------+
2 rows in set (0.00 sec)