从SQL表中删除重复的行

时间:2016-02-01 05:13:29

标签: sql sqlite

我有这样的预订表

place      day       name1     floor1    name2     floor2
---------  --------  --------- --------- --------- ---------
Anaheim    Monday    Sean      3rd       Jenny     2nd
Anaheim    Monday    Jenny     2nd       Sean      3rd
Cerritos   Saturday  Dennis    4th       Sean      3rd

如您所见,第一行和第二行只是重复,顺序不同。 我想要一个像

这样的决赛桌
place      day       name1     floor1    name2     floor2
---------  --------  --------- --------- --------- ---------
Anaheim    Monday    Sean      3rd       Jenny     2nd
Cerritos   Saturday  Dennis    4th       Sean      3rd

我在想这样的事情

SELECT t1.place, t1.day, t1.name1, t1.floor, t1.name2, t1.floor2
FROM table t1, table t2
WHERE NOT (t1.place = t2.place AND t1.day = t2.day AND
           t1.name1 = t2.name2 AND t1.floor1 = t1.floor2);

但这不起作用:(也许我的理解太短了......

我该如何处理?

修改
好吧,我应该提到这一点,但我正在寻找一个总体思路,而不是这个特定的表格。

可能有像

这样的表格
place      day       name1     floor1    section1   name2    floor2    section2
---------  --------  --------- --------- --------- --------- --------- -----------
Anaheim    Monday    Sean      HR        12         Jenny     QA       24
Anaheim    Monday    Jenny     QA        24         Sean      HR       12
Cerritos   Saturday  Dennis    Main      31         Sean      HR       12

在这种情况下,我不能使用任何“排序”和删除机制..

但是,谢谢大家为解决这个问题付出的努力!

3 个答案:

答案 0 :(得分:2)

使用聪明的GROUP BY

SELECT t1.place, t1.day, t1.name1, t1.floor, t1.name2, t1.floor2
FROM table t1
INNER JOIN
(
    SELECT t1.place, t1.day, MAX(t1.floor, t1.floor2) AS floor1,
        MIN(t1.floor, t1.floor2) AS floor2
    FROM table t1, table t2
    GROUP BY t1.place, t1.day, MAX(t1.floor, t1.floor2),
        MIN(t1.floor, t1.floor2)
) t2
ON t1.place = t2.place AND t1.day = t2.day AND t1.floor = t2.floor1 AND
    t1.floor2 = t2.floor2

答案 1 :(得分:1)

首先,如果您要将floor1与9个楼层进行比较,那么2nd将大于11th。要解决此问题,您需要从floor1中提取楼层编号,然后进行比较。

话虽如此,如果它适用于您的db / version,您可以使用此查询。

SQLFiddle Demo Fast version

通用版本就是这样的。

SQLFiddle Demo Generic verison

SELECT
  t.*
FROM table1 t
INNER JOIN (SELECT
  t1.place,
  t1.day,
  t1.name1
FROM table1 t1
INNER JOIN table1 t2
  ON t1.place = t2.place
  AND t1.day = t2.day
  AND CAST(REPLACE(REPLACE(REPLACE(REPLACE(t1.floor1, 'st', ''), 'nd', ''), 'rd', ''), 'th', '') AS decimal)
  <=
  CAST(REPLACE(REPLACE(REPLACE(REPLACE(t2.floor1, 'st', ''), 'nd', ''), 'rd', ''), 'th', '') AS decimal)
GROUP BY t1.place,
         t1.day,
         t1.floor1
HAVING COUNT(*) = 1) t3
  ON t.place = t3.place
  AND t.day = t3.day
  AND t.name1 = t3.name1

答案 2 :(得分:0)

使用函数LEASTGREATEST获取已排序的名称和楼层,然后通过连接地点,日期,名称和楼层列来对数据进行分组。

试试这个:

SELECT t1.*
FROM table1 t1
GROUP BY concat(t1.place,t1.day,least(name1,name2),greatest(name1,name2),
                least(floor1,floor2),greatest(floor1,floor2));

SQL小提琴:http://sqlfiddle.com/#!9/02fae/10