我有三个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
答案 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
答案 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;
以上内容不会显示那些应该具有空输出的专业(根据您的示例)。要获得该列表,请将最后一个内部联接转换为左外部联接。