ORACLE SQL比较同一个表中的两行或更多行

时间:2016-08-29 12:26:34

标签: sql oracle

我有一个表格,其值与此类似

Uname | Grp_ID | Role_ID
---------------------
usr1  | 10     | 1032
usr1  | 10     | 1034
usr1  | 20     | 1032
usr1  | 20     | 1034
usr1  | 30     | 1032
usr1  | 40     | 1032
usr1  | 50     | 1034
usr1  | 50     | 1034
usr1  | 60     | 1018
usr1  | 70     | 1057

我想要输出具有1032和1034(两者)的Grp_ID作为Role_ID 例如,

Grp_ID 10 has 1032 and 1034 as ROle_IDs
Grp_ID 20 has 1032 and 1034 as ROle_IDs

Grp_ID 30,40,50,60,70没有1032和1034作为Role_IDs

我尝试过使用内连接和'拥有'但似乎没有得到我想要的东西。

5 个答案:

答案 0 :(得分:1)

Select t1.uname, t2.grp_id, t1.role_id from table_name t1 
left join table_name t2 on t1.grp_is = t2.grp_id
Where t1.role_id = 1032 and t2.role_id = 1034

答案 1 :(得分:1)

您需要做的是将表连接到组ID上,然后筛选包含两个角色ID的行。参与联接的每个表都有不同的作用。如果你需要过滤3个值,那么你需要3个表子句(两个连接)。

WITH thetable AS (
  SELECT 10 grpid, 1032 roleid FROM dual UNION ALL
  SELECT 10 grpid, 1034 roleid FROM dual UNION ALL
  SELECT 20 grpid, 1032 roleid FROM dual UNION ALL
  SELECT 20 grpid, 1034 roleid FROM dual UNION ALL
  SELECT 30 grpid, 1032 roleid FROM dual UNION ALL
  SELECT 40 grpid, 1032 roleid FROM dual UNION ALL
  SELECT 50 grpid, 1034 roleid FROM dual UNION ALL
  SELECT 50 grpid, 1034 roleid FROM dual UNION ALL
  SELECT 60 grpid, 1018 roleid FROM dual UNION ALL
  SELECT 70 grpid, 1057 roleid FROM dual
)
SELECT t1.grpid, t1.roleid, t2.roleid
FROM thetable t1
JOIN thetable t2 ON t1.grpid = t2.grpid
WHERE t1.roleid = 1032 AND t2.roleid = 1034;


groupid  roleid  roleid_1
10       1032    1034
20       1032    1034

答案 2 :(得分:1)

我喜欢使用group byhaving解决这些问题。在这种情况下:

select grp_id
from tbl 
where role_id in (1032, 1034)
group by grp_id 
having count(distinct role_id) = 2;

我发现这种方法可以归结为集内问题的许多变体。

答案 3 :(得分:1)

只是提供一个不同的答案:

SELECT GrpID FROM theTable WHERE roleId = 1032
INTERSECT
SELECT GrpID FROM theTable WHERE roleID = 1034

SELECT 'Grp_ID '|| GRPID ||' has 1032 and 1034 as Role_IDs' 
FROM theTable 
WHERE roleId = 1032
INTERSECT
SELECT 'Grp_ID '|| GRPID ||' has 1032 and 1034 as Role_IDs' 
FROM theTable 
WHERE roleID = 1034

如果您需要问题中的全文......

但我不是在SQL表示层中添加这样的文本的忠实粉丝应该照顾它。

答案 4 :(得分:0)

正如@jarlh所说,这样做。在这里,我没有在uname

上使用过滤器
with tbl (Uname,Grp_ID,Role_ID) as 
(   select 'usr1',10,1032 from dual union all
    select 'usr1',10,1034 from dual union all
    select 'usr1',20,1032 from dual union all
    select 'usr1',20,1034 from dual union all
    select 'usr1',30,1032 from dual union all
    select 'usr1',40,1032 from dual union all
    select 'usr1',50,1034 from dual union all
    select 'usr1',50,1034 from dual union all
    select 'usr1',60,1018 from dual union all
    select 'usr1',70,1057 from dual
)
--Query
select grp_id
 ,count(distinct role_id) as count_dist_role_id 
from tbl 
where Role_ID in (1032,1034)
group by grp_id 
having count(distinct role_id)=2

输出

+--------+--------------------+
| GRP_ID | COUNT_DIST_ROLE_ID |
+--------+--------------------+
|     20 |                  2 |
|     10 |                  2 |
+--------+--------------------+