繁体   English   中英

SQL JOIN with WHERE 条件当两行的值相同并且一行匹配两个不同的行

[英]SQL JOIN with WHERE condition when two rows' values are the same and one row matches to two different rows

我有这些表:

CREATE TABLE students(
  id int NOT NULL PRIMARY KEY,
  name VARCHAR(30) NOT NULL
 );

CREATE TABLE studentsActivities(
  studentId int NOT NULL,
  activity VARCHAR(30) NOT NULL,
  PRIMARY KEY (studentId, activity),
  foreign KEY (studentId) REFERENCES students(id) 
);

我必须返回所有打网球或足球的学生姓名。 但是,有一个我无法通过的测试用例,它是这样说的:

同名学生。

我不知道测试用例的确切实现,但我怀疑是学生 A 叫 Carl 打网球,学生 B 也叫 Carl 打足球,Carl 出现两次的情况。 我如何查询该数据库以获得这样的结果? 我创建了演示库来尝试:

CREATE TABLE students(
  id int NOT NULL PRIMARY KEY,
  name VARCHAR(30) NOT NULL
 );

CREATE TABLE studentsActivities(
  studentId int NOT NULL,
  activity VARCHAR(30) NOT NULL,
  PRIMARY KEY (studentId, activity),
  foreign KEY (studentId) REFERENCES students(id) 
);

INSERT INTO students 
VALUES
(1, "Jeremy"),
(2, "Hannah"),
(3, "Luke"),
(4, "Frank"),
(5, "Sue"),
(6, "Sue"),
(7, "Peter");

INSERT INTO studentsActivities
VALUES
(1, "Tennis"),
(1, "Football"),
(2, "Running"),
(3, "Tennis"),
(4, "Football"),
(5, "Football"),
(6, "Tennis");

SQL 小提琴让我们假设传递集是:

Jeremy 
Luke 
Frank 
Sue 
Sue

我已经尝试过这两个查询,但没有一个给出正确的答案。

--- 1
SELECT s.name
FROM students s
JOIN studentsActivities sa
ON sa.studentId = s.id
WHERE activity = "Tennis"
UNION
SELECT s.name
FROM students s
JOIN studentsActivities sa
ON sa.studentId = s.id
WHERE activity = "Football"
--- Returns Frank Jeremy Luke Sue (missing one Sue)

--- 2
SELECT s.name
FROM students s
JOIN studentsActivities sa
ON sa.studentId = s.id
WHERE activity = "Tennis"
OR activity = "Football"
ORDER BY s.name;
--- Returns Frank Jeremy Jeremy Luke Sue Sue (too much Jeremies)

您可以使用exists

select s.*
from students s
where exists (
    select 1 
    from studentsActivities sa 
    where sa.studentId = s.id and sa.activity in ('Tennis', 'Football')
)

DB Fiddle 上的演示

id | name  
-: | :-----
 1 | Jeremy
 3 | Luke  
 4 | Frank 
 5 | Sue   
 6 | Sue   

加入表格,仅过滤包含您想要的活动的行并返回不同的行:

select distinct s.id, s.name
from students s inner join studentsActivities a
on a.studentId = s.id
where a.activity in ('Tennis', 'Football')

演示

结果:

| id  | name   |
| --- | ------ |
| 1   | Jeremy |
| 3   | Luke   |
| 4   | Frank  |
| 5   | Sue    |
| 6   | Sue    |

如果您只想要没有 id 的学生姓名:

select s.name
from students s inner join studentsActivities a
on a.studentId = s.id
where a.activity in ('Tennis', 'Football')
group by s.id, s.name

演示

结果:

| name   |
| ------ |
| Jeremy |
| Luke   |
| Frank  |
| Sue    |
| Sue    |

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM