删除与其他表匹配的重复行

时间:2014-02-14 12:50:43

标签: postgresql

我有两张桌子

  Table A                        Table B
  --------                      ---------

  a  b  c                       a  b  c
  a  b  c                       a  b  c
  a  b  c                       a  b  c
  e  f  g                       a  b  c
  h  i  j                       e  f  g
  k  l  m                       k  l  m
                                k  l  m
                                x  y  z
                                s  t  u
                                a  b  c
                                a  b  c

现在我想删除表B中与第1列,第2列和第3列匹配的行与表A,其中表B中每个重复行的计数应小于或等于表A.

所以输出应该是

  Table A                        Table B
  --------                      ---------

  a  b  c                       a  b  c
  a  b  c                       a  b  c
  a  b  c                       a  b  c
  e  f  g                       e  f  g
  h  i  j                       k  l  m
  k  l  m                       x  y  z                                                                      
                                s  t  u

我尝试过使用内部连接和交叉但未能获得所需的结果。

2 个答案:

答案 0 :(得分:2)

尝试:

DELETE FROM tableB
WHERE ctid IN (
   SELECT BB.ctid
   FROM (
     SELECT a, b, c, count(*) cnt
     FROM tablea
     GROUP BY a, b, c
   ) AA
   JOIN (
     SELECT ctid, 
            a, b, c, 
            row_number() over (partition by a,b,c) cnt
     FROM tableb
   ) BB
   ON AA.a = BB.a
      AND AA.b = BB.b
      AND AA.c = BB.c
      AND AA.cnt < BB.cnt
)

演示:http://sqlfiddle.com/#!12/73e99/1

答案 1 :(得分:-2)

我认为如果表格不大,那么简单的方法就是删除TableA中存在的TableB中的所有行,然后将TableA插入TableB中。另一种方法是在表B中至少需要一个主键。

DELETE FROM TableB 
            WHERE EXISTS(SELECT * FROM TableA 
                                   WHERE C1=TableA.C1 
                                         AND C2=TableA.C2 
                                         AND C3=TableA.C3) ;

INSERT INTO TableB SELECT * FROM TableA;