Sql 选择colA中相同值但colB中不同值的行w/condition?

Sql 选择colA中相同值但colB中不同值的行w/condition?,sql,sql-server,database,Sql,Sql Server,Database,我在SQL Server中有一个表,其结构如下: id m_id r_id ------------------- 1 1 1 2 2 2 3 2 2 4 3 2 5 3 5 6 4 5 7 5 3 with r as ( select * from (values (2), (5)) v(r_id)

我在SQL Server中有一个表,其结构如下:

id     m_id    r_id
-------------------
1      1       1
2      2       2
3      2       2
4      3       2
5      3       5
6      4       5
7      5       3
with r as (
      select *
      from (values (2), (5)) v(r_id)
     )
select m_id
from t left join
     r
     on t.r_id = r.r_id
group by m_id
having count(*) = count(r.r_id) and  -- all ids match
       count(distinct t.r_id) = (select count(*) from r);
我需要弄清楚如何获得记录的m_id,其中r_id不同,但只有2或5的值

所以查询将产生这些行

m_id    r_id
-------------
3       2
3       5
如果我能在下注的地方得到m_ID,这样我就能更新那些记录,那就更好了

m_id
----
3
顺便说一句,我是否可以阅读一些好的资源,比如一本书或一个网站,以便从根本上掌握数据库查询?

使用聚合:

SELECT m_id
FROM mytable
GROUP BY m_id
HAVING 
    COUNT(*) = 2
    AND MIN(r_id) = 2
    AND MAX(r_id) = 5
与示例数据一起返回:

| m_id | | ---: | | 3 | |m_id| | ---: | | 3 |
你可以有重复的。我想我会选择:

select m_id
from t
group by m_id
having sum(case when r_id = 2 then 1 else 0 end) > 0 and
       sum(case when r_id = 5 then 1 else 0 end) > 0 and
       sum(case when r_id not in (2, 5) then 1 else 0 end) = 0 ;
也可以在不使用条件聚合构造的情况下执行此操作:

select m_id
from t
group by m_id
having min(r_id) = 2 and
       max(r_id) = 5 and
       count(distinct r_id) = 2;
但是,这并不容易推广到其他值

实际上,对于一般化,您可能会喜欢这样:

id     m_id    r_id
-------------------
1      1       1
2      2       2
3      2       2
4      3       2
5      3       5
6      4       5
7      5       3
with r as (
      select *
      from (values (2), (5)) v(r_id)
     )
select m_id
from t left join
     r
     on t.r_id = r.r_id
group by m_id
having count(*) = count(r.r_id) and  -- all ids match
       count(distinct t.r_id) = (select count(*) from r);

您可以选择满足您的条件的不同m_id:

要在sql上执行此操作,您需要执行以下操作(不是将其编写为!-=):


取所有与r_id不同的m_id,r_id仅为与3或5不同的m_id。从该子组中,您选择不同的m_id以获得“3”的结果。Distinct去掉了前面结果中的重复,即“选择”中的重复。

我想我喜欢其他答案可能更好;但为了以防万一,这里有一个使用exists的示例:

declare @table table (m_id int, r_id int)
insert into @table
values (1,2),(2,2),(2,2),(3,2),(3,5),(4,5),(5,3),(4,2),(4,4)

select distinct m_id
from @table t
where exists (select m_id from @table where r_id = 2 and m_id = t.m_id)
   and exists (select m_id from @table where r_id = 5 and m_id = t.m_id)
   and not exists (select m_id from @table where r_id not in (2, 5) and m_id = t.m_id)

第三个是给我正确的结果加上
警告:通过聚合或其他集合操作消除空值。
@avery\u larry。你不必担心警告。我有(m_id=3或m_id=5)而不是(m_id=2或m_id=5)。愚蠢的打字错误。现在很好不,不,现在不好。