假设你有一个如下所示的表格布局:
couses :
id (INT),
courseName (VARCHAR)
指导员:
id (INT),
courseId(INT),
instructor(VARCHAR)
创建一个将打印所有课程的查询,如果有一位教师,则显示他们的姓名,如果有两位教师,则按排序顺序在行上打印他们的名字,如果有两位以上的教师而不是教师姓名显示“委员会”。
例如,您的输出看起来像这样
courseId instructor1 instructor2 0 Edward Yourdon 1 Edward Dijkstra Nicholas Wirth 2 Comittee
注意:摘自TheDailyWtf的调查问卷。不是作业问题。
答案 0 :(得分:7)
是的,是的,商业逻辑等。这是一个游戏,而不是你老板要求你这样做。
在T-SQL中:
select
id
, courseName
, case (select count(*) from instructors i where i.courseid=c.courseid)
when 0 then 'No Instructor'
when 1 then (select top 1 instructor from instructors where i.courseid=c.courseid)
when 2 then (select top 1 instructor from instructors where i.courseid=c.courseid order by instructor desc)
else 'Committee'
end as instructor_1
, case (select count(*) from instructors i where i.courseid=c.courseid)
when 2 then (select top 1 instructor from instructors where i.courseid=c.courseid order by instructor asc)
else ''
end as instructor_2
from courses c
答案 1 :(得分:3)
在SQL Anywhere中,您可以通过以下方式执行此操作:
select courseid as cid,
if ( select count(*) from instructor where courseid = cid ) > 2
then 'Committee'
else
list(name order by name)
endif as profs
from instructor
group by courseid
order by cid
请注意,这会选择“教授”作为教授名单(如问题所述)作为单一栏目。
我对MySQL不太熟悉,知道是否有与list()
函数等价的内容。
答案 2 :(得分:2)
我认为这会奏效,但我还没有测试过。如果您决定要开始显示3个教师或4个或更多教师,那么它的可扩展性不是很高。
SELECT
C.id AS course_id,
CASE
WHEN I3 IS NOT NULL THEN 'Committee'
ELSE I1.instructor + COALESCE(', ' + I2.instructor, '')
END AS instructors
FROM
Courses C
LEFT OUTER JOIN Instructors I1 ON
I1.course_id = C.id
LEFT OUTER JOIN Instructors I_CHK1 ON
I_CHK1.course_id = C.id AND
I_CHK1.instructor < I1.instructor
LEFT OUTER JOIN Instructors I2 ON
I2.course_id = C.id AND
I2.instructor > I1.instructor
LEFT OUTER JOIN Instructors I_CHK2 ON
I_CHK2.course_id = C.id AND
I_CHK2.instructor > I1.instructor AND
I_CHK2.instructor < I2.instructor
LEFT OUTER JOIN Instructors I_CHK2 ON
I3.course_id = C.id AND
I3.instructor > I2.instructor AND
WHERE
I_CHK1.id IS NULL AND
I_CHK2.id IS NULL
答案 3 :(得分:1)
您要查找的是“数据透视表”或“交叉表”报告。它们可以使用普通的SQL:
此处可能还有其他问题,还有更多信息。查看此处的信息,其中显示了如何在SQL或应用程序逻辑中执行此操作(通过连续查询):
答案 4 :(得分:1)
这不是世界上最好的查询,但在所有的丑陋中,我有点喜欢它。具体来说,我喜欢这样一个事实,即您不必处理多个案例陈述,如果您有许多字段需要应用案例,这可能会很痛苦:
--- Single instructor case.
select
c.id as courseId, i.instructor as instructor1, null as instructor2
from
courses as c inner join instructors as i on i.courseId = c.id
where
(
select
count(instructor)
from
instructors as i2
where
i2.courseId = c.id
) = 1
union
--- Committee case.
select
c.id as courseId, "committee" as instructor1, null as instructor2
from
courses as c inner join instructors as i on i.courseId = c.id
where
(
select
count(instructor)
from
instructors as i2
where
i2.courseId = c.id
) > 2
union
--- Two instructor case.
select
c.id as courseId, i1.instructor as instructor1,
i2.instructor as instructor2
from
courses as c, instructor as i1, instructor as i2
where
--- Course ids must match.
c.id = i1.courseId and c.id = i2.courseId and
--- Instructor ids do not match.
i1.id <> i2.id and
--- There are only two instructors.
(
select
count(instructor)
from
instructors as i2
where
i2.courseId = c.id
) > 2
答案 5 :(得分:0)
另一种选择。注意:
1-我不相信到目前为止提供的任何解决方案都可以在SQL方言之间移植。如果允许第4列计数(*),我相信以下解决方案可以非常便携,因为它主要使用“标准SQL”。但是我只在SQLite3上测试过。
2-我故意通过复制couses表的错误来坚持你的规范。 [我猜它本来是课程而不是课程]
select
c.id, c.courseName, i.instructor as instructor1, null as instructor2
from
couses c, instructors i
where
c.id = i.courseId
group by
courseId having count(*) = 1
union
select /* Case 2: Two instructors */
c.id, c.courseName, i1.instructor as instructor1, i2.instructor as instructor2
from
couses c, instructors i1, instructors i2
where
c.id = i1.courseId and c.id = i2.courseId and i1.id != i2.id and i1.id < i2.id
group by
c.id having count(*) = 1
union
select /* Case 3: Three or more instructors */
c.id, c.courseName, "Commitee" as instructor1, null as instructor2
from
couses c, instructors i1, instructors i2, instructors i3
where
c.id = i1.courseId and c.id = i2.courseId and c.id = i3.courseId and
i1.id != i2.id and i1.id != i3.id and i2.id != i3.id and i1.id < i2.id
and i2.id < i3.id