Table1: Students
ID Name EternalToken
200901212 Joe xxxxxx
200809922 David yyyyyy
201009122 Chris zzzzzz
Table2: Banned
ID StudentID
1 200901212
我想选择所有学生,并显示一个附加字段,该学生通过隐藏EternalToken来表明该学生已被禁止
SELECT * FROM Students s
LEFT JOIN Banned b
ON s.ID = b.StudentID
这将同时显示两个表。但是,我希望结果是这样的:
ID Name EternalToken Banned
200901212 Joe NULL 1
200809922 David yyyyyy 0
201009122 Chris zzzzzz 0
只有被禁止的学生才应该有EternalToken = NULL
请注意,这只是我要实现的目标的一个示例,并不完全是我在做什么。 学生和被禁止的只是一个例子,我知道这不是多对多的关系,所以我只能在一张桌子上就可以做到。但是从技术上回答这个问题将极大地帮助我实现灵活的解决方案。
答案 0 :(得分:1)
您可以使用以下查询:
SELECT
s.ID,
s.Name,
CASE WHEN b.StudentID IS NOT NULL THEN NULL ELSE s.EternalToken END AS EternalToken,
CASE WHEN b.StudentID IS NULL THEN 0 ELSE 1 END AS Banned
FROM Students s
LEFT JOIN Banned b
ON s.ID = b.StudentID;
请注意,这与COALESCE
函数的作用相反。 COALESCE
检查一个值,如果该值为NULL
,则返回一个备用值。上面用于令牌的CASE
表达式检查值是否为 not NULL
,并在这种情况下返回NULL
,否则将显示永恒的令牌值。>
答案 1 :(得分:0)
使用case
和exists
:
SELECT s.*,
(CASE WHEN EXISTS (SELECT 1 FROM banned b WHERE s.ID = b.StudentID)
THEN 1 ELSE 0
END) as is_banned
FROM Students s ;
在MySQL中,您实际上可以将其简化为:
SELECT s.*,
( EXISTS (SELECT 1 FROM banned b WHERE s.ID = b.StudentID) ) as is_banned
FROM Students s ;
与EXISTS
方法相比,我更喜欢LEFT JOIN
,因为逻辑清楚地表明不会添加任何行。当LEFT JOIN
中有重复项时,banned
将使行数相乘。