如何查询具有相同值的组的SQL

时间:2013-03-04 02:10:56

标签: sql oracle

我有三个Oracle数据库表。我将创建一个人为的例子,让它更容易一些:

兽医表..

vid         name
1           Bob
2           Sally
3           Sue
4           Henry

spid    Animal

1       Dogs
2       Cats
3       Mice
4       Kangaroos
5       Koala Bears

广告

id     vid   spid               Ad venue

1       1      1                 TV ads
2       1      2                 TV ads
3       1      2                 Magazine ads
4       2      1                 TV ads
5       2      1                 On line ads
6       3      5                 TV ads
7       4      5                 Magazine ads

我想获得前3个兽医的结果集,每个专业只宣传一个专业。对某些专业而言,没有兽医可以宣传这一专业。 'vets'表中有大约30,000行。 Specialties表只有10行。 广告表有大约100,000行。我知道如何进行查询和连接,但不知道如何查找组内所有相同的行。

所以我正在寻找这样的输出:

 Dogs          null
 Cats          Sally
 Mice          null
 Kangaroos     null
 Koala Bears   Sue, Henry

3 个答案:

答案 0 :(得分:2)

select
   max(animal) as animal,
   listagg(name, ', ') within group (order by name) as vet_list
from
   Specialties
   left join (
      select
         vid,
         max(spid) as spid,
         row_number() over(partition by max(spid) order by null) rn
      from Advertising
      group by vid
      having count(distinct spid) = 1
   ) using(spid)
   left join veterinarians using(vid)
where lnnvl(rn > 3)
group by spid
order by spid

fiddle

答案 1 :(得分:1)

这为您提供了仅宣传1个专业的兽医

SELECT vid
FROM advertising
GROUP BY vid
HAVING COUNT(*)=1

这为您提供了每个类别中具有1个专业的所有兽医

SELECT s.Animal, v.name
FROM Specialties s
     LEFT JOIN
     advertising a ON s.spid=a.spid
     LEFT JOIN
     veterinarians v ON a.vid=v.vid
WHERE a.vid IN (SELECT vid
                FROM advertising
                GROUP BY vid
                HAVING COUNT(*)=1)

现在,您没有在此上下文中指定“first”的含义 - 按字母顺序,通过id,还有其他内容?当您决定时,可以按此进行分区。

答案 2 :(得分:0)

尝试以下方法: -

select vid
from (select distinct vid, spid
from advertising)
group by vid
having count(*) = 1;

上面将列出所有那些只有1个专业的兽医。要获得相应专业的列表,请执行以下操作: -

select * from
(select s.spid,s.animal, a.vid,v.name,row_number() over (partition by s.spid order by a.vid) rn
from specialities s inner join advertising a
on s.spid=a.spid
inner join vets v
on a.vid=v.vid
and v.vid in (select vid
    from (select distinct vid, spid
    from advertising)
    group by vid
    having count(*) = 1)
order by s.spid
)
where rn <= 3;

以上内容不会显示那些应该具有空输出的专业(根据您的示例)。要获得该列表,请将最后一个内部联接转换为左外部联接。