4

我有一个包含冗余数据的表,我正在尝试识别所有具有重复子行的行(因为没有更好的词)。通过子行,我的意思是考虑COL1并且COL2只考虑。

所以假设我有这样的事情:

 COL1   COL2   COL3
 ---------------------
 aa     111    blah_x
 aa     111    blah_j
 aa     112    blah_m
 ab     111    blah_s
 bb     112    blah_d
 bb     112    blah_d
 cc     112    blah_w
 cc     113    blah_p

我需要一个返回这个的 SQL 查询:

 COL1   COL2   COL3
 ---------------------
 aa     111    blah_x
 aa     111    blah_j
 bb     112    blah_d
 bb     112    blah_d
4

10 回答 10

8

这对你有用吗?

select t.* from table t
left join ( select col1, col2, count(*) as count from table group by col1, col2 ) c on t.col1=c.col1 and t.col2=c.col2
where c.count > 1
于 2008-09-25T01:40:43.843 回答
5

使用您列出的数据,您的查询是不可能的。第 5 行和第 6 行的数据本身并没有区别。

假设您的表名为“quux”,如果您从以下内容开始:

SELECT a.COL1, a.COL2, a.COL3 
FROM quux a, quux b
WHERE a.COL1 = b.COL1 AND a.COL2 = b.COL2 AND a.COL3 <> b.COL3
ORDER BY a.COL1, a.COL2

你最终会得到这个答案:

 COL1   COL2   COL3
 ---------------------
 aa     111    blah_x
 aa     111    blah_j

这是因为第 5 行和第 6 行的 COL3 值相同。任何同时返回第 5 行和第 6 行的查询也将返回此数据集中所有行的重复项。

另一方面,如果你有一个主键 (ID),那么你可以使用这个查询来代替:

SELECT a.COL1, a.COL2, a.COL3
FROM quux a, quux b
WHERE a.COL1 = b.COL1 AND a.COL2 = b.COL2 AND a.ID <> b.ID
ORDER BY a.COL1, a.COL2

[编辑以简化 WHERE 子句]

你会得到你想要的结果:

COL1   COL2   COL3
---------------------
aa     111    blah_x
aa     111    blah_j
bb     112    blah_d
bb     112    blah_d

我刚刚在 SQL Server 2000 上对此进行了测试,但是您应该在任何现代 SQL 数据库上看到相同的结果。

blorgbeard证明我错了——对他有好处!

于 2008-09-25T01:40:02.833 回答
4

像这样加入自己:

SELECT a.col3, b.col3, a.col1, a.col2 
FROM tablename a, tablename b
WHERE a.col1 = b.col1 AND a.col2 = b.col2 AND a.col3 != b.col3

如果您使用的是 postgresql,则可以使用 oid 使其返回较少重复的结果,如下所示:

SELECT a.col3, b.col3, a.col1, a.col2 
FROM tablename a, tablename b
WHERE a.col1 = b.col1 AND a.col2 = b.col2 AND a.col3 != b.col3
  AND a.oid < b.oid
于 2008-09-25T01:35:57.350 回答
2

没有方便的数据库来测试这个,但我认为它应该可以工作......

select
  *
from
  theTable
where
  col1 in
    (
    select
      col1
    from
      theTable
    group by
      col1||col2
    having
      count(col1||col2) > 1
    )
于 2008-09-25T01:37:40.123 回答
2

我天真的尝试是

select a.*, b.* from table a, table b where a.col1 = b.col1 and a.col2 = b.col2 and a.col3 != b.col3;

但这将返回所有行两次。我不确定您如何将其限制为仅退回一次。也许如果有一个主键,你可以添加“and a.pkey < b.pkey”。

就像我说的那样,这并不优雅,可能有更好的方法来做到这一点。

于 2008-09-25T01:38:39.060 回答
2

像这样的东西应该工作:

SELECT a.COL1, a.COL2, a.COL3
FROM YourTable a
JOIN YourTable b ON b.COL1 = a.COL1 AND b.COL2 = a.COL2 AND b.COL3 <> a.COL3

通常,JOIN 子句应包括您认为属于“重复”的每一列(在本例中为 COL1 和 COL2),以及至少一列(或尽可能多的列)以消除行连接到它自己(在这种情况下是 COL3)。

于 2008-09-25T01:43:11.530 回答
2

这与自连接非常相似,只是它没有重复项。

select COL1,COL2,COL3
from theTable a
where exists (select 'x'
              from theTable b
              where a.col1=b.col1
              and   a.col2=b.col2
              and   a.col3<>b.col3)
order by col1,col2,col3
于 2008-09-25T01:48:08.460 回答
1

以下是查找重复项的方法。使用您的数据在 oracle 10g 中进行了测试。

select * from tst where (col1, col2) in (select col1, col2 from tst group by col1, col2 with count(*) > 1)

于 2008-10-01T04:46:39.937 回答
0

选择 COL1、COL2、COL3

从表

按 COL1、COL2、COL3 分组

计数(*)> 1

于 2008-09-25T02:43:10.263 回答
0

忘记连接——使用分析函数:

select col1, col2, col3
from
(
select col1, col2, col3, count(*) over (partition by col1, col2) rows_per_col1_col2
from table
)
where rows_per_col1_col2 > 1
于 2008-09-25T03:27:28.783 回答