Sql 在每个组的2列中选择值相等的所有行

Sql 在每个组的2列中选择值相等的所有行,sql,h2,Sql,H2,考虑下表 ID || YEAR || TERM || NAME || UNIT ---------------------------------------- 1 || 1985 || 1 || MARIE || 01VS 1 || 1986 || 2 || MARIE || 01VS 1 || 1986 || 2 || MARIE || 07GB 1 || 1986 || 3 || MARIE ||

考虑下表

ID   || YEAR  || TERM  || NAME   || UNIT    
----------------------------------------
1    || 1985  || 1     || MARIE  || 01VS
1    || 1986  || 2     || MARIE  || 01VS
1    || 1986  || 2     || MARIE  || 07GB 
1    || 1986  || 3     || MARIE  || 07GB
2    || 1992  || 1     || AVALON || 01VS
2    || 1992  || 2     || AVALON || 01VS
2    || 1992  || 3     || AVALON || 01VS
3    || 2001  || 1     || DENIS  || 08HK
3    || 2001  || 1     || DENIS  || 07GB
3    || 2001  || 2     || DENIS  || 08HK
3    || 2002  || 1     || DENIS  || 08HK
我想在H2中编写一个sql查询,它将返回每个ID的所有行,其中年份和期限的值相等。因此,对于上表,结果应如下所示:

ID   || YEAR  || TERM  || NAME   || UNIT    
----------------------------------------
1    || 1986  || 2     || MARIE  || 01VS
1    || 1986  || 2     || MARIE  || 07GB
3    || 2001  || 1     || DENIS  || 08HK
3    || 2001  || 1     || DENIS  || 07GB

我想下面这样的方法会管用的

select *
from table t
where exists (select id, term from table t2 
where t2.id = t.id 
and t2.term = t.term
group by id, term
having count(*) > 1)
但是,如果表中有某种主键,则会更容易

您可以使用exists:


使用GROUPBY和HAVING将表连接到子查询如何

select t.*
from yourtable t
join 
(
    select ID, YEAR, TERM
    from yourtable 
    group by ID, YEAR, TERM
    having count(*) > 1
) d on (d.ID = t.ID and d.YEAR = t.YEAR and d.TERM = t.TERM);

如果我为每一行创建一个唯一的行ID呢。在某种程度上,这有助于简化解决方案吗。您可以在存在的地方从表2中选择*,其中t2.primarykey t.primarykey和t2.id=t.id和t2.term=t.id。更简单的一点是,您只查找表中另一条记录的期限和id值相同的记录。group by和count也这样做,但效率稍低。顺便问一下,它的期限和年份不是id?我希望这是平等的。但我明白你的意思。谢谢:如果有人有3个相同ID、年份、期限和姓名的记录,但在单位中不匹配。。。。你想在结果中看到6条记录,比如A,B,C:AC,BC,BA,BC,CA,CB吗?还是只有3个?AB,AC,BC3。就像上面ID1的例子一样,我们有两条记录具有相同的ID、年份、期限和名称,但单位不匹配。因此,结果输出只有这两行。
select t.*
from yourtable t
join 
(
    select ID, YEAR, TERM
    from yourtable 
    group by ID, YEAR, TERM
    having count(*) > 1
) d on (d.ID = t.ID and d.YEAR = t.YEAR and d.TERM = t.TERM);