将列有2列子行的所有行重复列出的SQL查询是什么?

时间:2020-03-06 14:41:58  来源:igfitidea点击:

好的,我有一个包含冗余数据的表,并且我试图识别所有具有重复子行的行(因为缺少更好的单词)。所谓子行,是指仅考虑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

解决方案

像这样加入自己:

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

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

select
  *
from
  theTable
where
  col1 in
    (
    select
      col1
    from
      theTable
    group by
      col1||col2
    having
      count(col1||col2) > 1
    )

我天真的尝试是

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

但这将两次返回所有行。我不确定我们如何将其限制为只返回一次。也许如果有主键,则可以添加"和a.pkey <b.pkey"。

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

使用列出的数据,我们无法进行查询。第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证明了我错了-对他有好处!

这对我们有用吗?

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

这样的事情应该起作用:

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)。

这与自联接非常相似,只不过它没有重复项。

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

选择COL1,COL2,COL3

从表

按COL1,COL2,COL3分组

计数(*)> 1

忘记加入-使用分析功能:

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

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

选择从tst
其中(col1,col2)在
(从tst组中按col1选择col1,col2,col2的count(
)> 1)