2013-03-04 41 views
2

我有三个Oracle数据库表。我将创建一个人为的例子,使其更容易一些:如何为具有相同值的组查询SQL

兽医的表..

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名兽医的结果集,这些兽医只宣传一种专业。对于某些专业来说,NO vet可能只是宣传那一种专业。 '兽医'表有大约30,000行。 Specialties表只有10行。 广告桌有大约100,000行。我知道如何进行查询和连接,但不知道如何查找组中所有相同的行。

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

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

回答

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

+0

非常感谢您的工作!非常感激。 – Leonard 2013-03-04 18:58:28

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) 

现在,您尚未在此上下文中指定“第一”的含义 - 按字母顺序,由身份证,别的东西?当你决定时,你可以通过这个进行分区。

+0

有趣和有用的开始。谢谢。尽管如此,它并没有让我在我想要的地方。条件计数(*)= 1只在他们仅在1个媒体上投放广告时才会成立,如果我正确阅读此内容。如果在电视和杂志上刊登相同的专业(袋鼠),他们将不会被发现。 – Leonard 2013-03-04 03:13:59

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; 

以上将不显示了应有空输出的专科(根据你的例子)。为了得到这个列表,将最后一个内部联接转换为一个左外部联接。

+0

我收到以下错误:ORA-30485:缺少窗口规范中的ORDER BY表达式 30485. 00000 - “窗口规范中缺少ORDER BY表达式” *原因:或者ORDER BY表达式对于此函数是必需的,或者 有一个聚合组没有ORDER按表达式。 *操作: 错误在行:18列:31 – Leonard 2013-03-04 04:21:46

+0

更新了代码 – Max 2013-03-04 15:17:20

+0

感谢您的工作。对此,我真的非常感激。我仍然有错误必须与实际选择* ...声称它是模糊的。当我尝试其他选择元素时,也出现了“模棱两可”。但是,再次感谢。 – Leonard 2013-03-04 19:00:09

相关问题