使用子查询进行比较

Posted

技术标签:

【中文标题】使用子查询进行比较【英文标题】:comparing using sub-queries 【发布时间】:2013-02-11 07:14:18 【问题描述】:

这是我试图回答的问题:

我拥有的是:

SELECT DISTINCT a1.acnum
FROM academic a1, academic a2
WHERE a1.deptnum = a2.deptnum
AND a1.acnum <> a2.acnum
AND a1.acnum IN (Select acnum
from interest
group by acnum
having count(acnum) >1);

这是错误的,因为我正在做的是 如果 acnum(学号)218 与 acnum 217 在同一部门工作,并且与 acnum 199(diff 部门)有相同的兴趣,那么我将 acnum 218 添加到列表中。

但是,我应该只添加 acnum 218 和 217,如果它们具有相同数量的领域兴趣。

interest 表有 fieldnum , acnum

学术表有acnum、deptnum、name

部门表有deptnum,deptName

 FIELDNUM           ACNUM DESCRIP                                                                        
------------------ -------------------- 
292                 100  Multiprocessor and Special purpose computer design                               
293                 100  General (HW)                                                                     
293                 197  Computer architecture  



                                                      

输出应该只列出所有学者的编号.. 但要说清楚一点:

Acnum Deptnum Interest
1        1       g&f
2        1       g&f
3        2        f
4        3        l
5        4       r&l
6        4       r&l

输出应该是: 1 2 5 6

【问题讨论】:

如果您提供示例数据和预期输出会很好 您使用的是哪个 DBMS?甲骨文? Postgres? 【参考方案1】:

未经测试,但应该很好

SELECT DISTINCT a1.acnum
FROM academic a1
INNER JOIN academic a2 ON a1.deptnum = a2.deptnum
                          AND 
                          a1.acnum <> a2.acnum
INNER JOIN interest i1 ON a1.acnum=i1.acnum
GROUP BY a1.acnum
HAVING COUNT(i1.acnum)=(SELECT COUNT(*)
                        FROM interest i2
                        WHERE i1.acnum=i2.acnum)

【讨论】:

谢谢你..我会试着理解你在几分钟内做了什么..但我测试了它,我得到了一个错误..“不是 GROUP BY 表达式” 最后一位:> (SELECT COUNT(i2.acnum) > FROM interest i2 > WHERE i1.acnum=i2.acnum) 我不认为放置“i1.acnum”是正确的.. 因为我们只有兴趣 i2【参考方案2】:

也许在这里使用JOIN 可以给你更好的结果:

SELECT DISTINCT a1.acnum
FROM academic a1
JOIN academic a2
ON a1.deptnum = a2.deptnum
AND a1.acnum <> a2.acnum
AND a1.acnum IN (Select acnum
from interest
group by acnum
having count(acnum) >1);

【讨论】:

谢谢.. 但我认为问题出在我的逻辑上.. :)【参考方案3】:

根据我的理解,它应该可以工作

SELECT 
      listagg(a1.acnum,',') within group( order by a1.acnum) , a1.deptnum,a2.cnt
FROM 
     academic a1,
     (Select 
            acnum,count(*) as cnt
      from interest
      group by acnum
     ) a2
where 
     a1.acnum=a2.acnum
group by 
     a1.deptnum,a2.cnt
having count(*)>1;

【讨论】:

【参考方案4】:

使用公用表表达式(子查询)来获取学者、他们的部门和他们的兴趣计数。然后从中查询两次以获得所需的输出。

with cte as ( select a.acnum
                     , a.deptnum
                     , count(i.acnum) as int_cnt
              from academic a
                   , interest i
              where i.acnum = a.acnum
              group by  a.acnum
                     , a.deptnum
            )
select ct1.acnum
       , cte1.deptnum
       , cte1.in_cnt
from cte cte1
     , cte cte2
where cte2.deptnum = cte1.deptnum 
and cte2.int_cnt = cte1.int_cnt  
and cte2.acnum != cte1.acnum 
order by cte1.deptnum
         , cte1.acnum

警告 - 未经实际测试,因此虽然逻辑合理,但语法可能有问题;)

【讨论】:

以上是关于使用子查询进行比较的主要内容,如果未能解决你的问题,请参考以下文章

使用子查询将价格列与类别的平均价格进行比较

sql怎么用查询结果作为条件进行查询

SQL 基础之使用子查询检索数据(二十二)

17/12/6 子查询

SQL基础教程(第2版)第5章 复杂查询:5-3 关联子查询

子查询的概念