嗨,我有个问题,我需要这样做:
-For每一位只上瑜伽课的教练,都要说出自己的名字、姓和健身房的所在城市,在那里他上的课是最多的。
从本表:
教练(SSN*,NameT,姓氏,城市)
健身房(CodG*,NameG,地址,城市)
专业(CodS*,NameS,描述)
课程(SSN*,CodG*,Date*,CodS,ParticipantsNumber)
星号是主键。我现在所做的是:
SELECT T.Name,T.Surname,G.City
FROM TRAINER AS T,LESSON AS L,SPECIALTY AS S,GYM AS G
WHERE T.SSN=L.SSN AND S.CodS=L.CodS AND G.CodG=L.CodG
AND T.SSN NOT IN(/*SSN of instructor who have given at least one lesson other than Yoga*/
SELECT T1.SSN
FROM TRAINER AS T1,LESSON AS L1,SPECIALTY AS S1
WHERE T1.SSN=L1.SSN AND S1.CodS=L1.CodS AND S1.NameS<>'Yoga')
我真正不能做的是,健身房里有最多的课程,因为据我所知,MAX(COUNT *)是不可行的,也许这可以通过查询之间的关联来完成,但我不知道如何做到。
任何帮助都会得到很大的帮助,谢谢!
P.S I主要使用APEX ORACLE
发布于 2022-05-05 15:52:28
我会这样做:
select t.namet, t.surname, g.city
from (
select ssn, min(codg) keep (dense_rank last order by cnt) as codg
from (
select ssn, codg, count(*) as cnt
from lesson
where ssn in (
select ssn
from trainer
where ssn not in (
select l.ssn
from lesson l join specialty s on l.cods = s.cods
where s.names <> 'Yoga'
)
)
group by ssn, codg
)
group by ssn
) sq
join trainer t on t.ssn = sq.ssn
join gym g on g.codg = sq.codg
;
重担是在子查询sq
中完成的--找到只教瑜伽的训练员的ssn
,然后为每个这样的老师在每个健身房数课,只选择上课次数最多的健身房(在最高次数的健身房中代码最低的健身房,如果是领带)。注意在select
列表中使用的聚合函数select
:min(codg) keep (dense_rank LAST order by cnt)
--这是一个非常有用的聚合函数,显然许多程序员从未学习过。
剩下的就是参加训练员和健身房桌的琐碎工作。
注意-虽然我没有使用with
子句(也许他们还没有教它),但我仍然选择使用现代的ANSI连接语法,而不是他们似乎教你的东西。您可能需要问您的教员:(1)他们为什么使用旧的Oracle语法,即使是Oracle自己也推荐使用而不是;(2)检查上一个表中的列名DATE
。这是一个保留关键字;它不能将用作列名。你的教练应该更清楚。
发布于 2022-05-05 15:21:31
从将count(1) as num_times
添加到原始查询开始,然后使用row_number()查找排名,然后只过滤那些有_rank=1
的
with data as (
SELECT T.Name,T.Surname,G.City, count(1) as num_times
FROM TRAINER AS T,LESSON AS L,SPECIALTY AS S,GYM AS G
WHERE T.SSN=L.SSN AND S.CodS=L.CodS AND G.CodG=L.CodG
AND T.SSN NOT IN(/*SSN of instructor who have given at least one lesson other than Yoga*/
SELECT T1.SSN
FROM TRAINER AS T1,LESSON AS L1,SPECIALTY AS S1
WHERE T1.SSN=L1.SSN AND S1.CodS=L1.CodS AND S1.NameS<>'Yoga'),
first_pass as (
group by T.Name,T.Surname,G.City)
select
*, row_number() over (partition by name, surname order by num_times desc) as _rank
)
select * from first_pass where _rank = 1
https://stackoverflow.com/questions/72129456
复制相似问题