我想知道是否可以将内连接与另一个内连接内连接。
我有一个3个表的数据库:
的人
的运动员
教练
每个运动员或教练必须存在于人员表中,但有些人既不是教练也不是运动员。
我要做的是找到至少3种不同运动中活跃(意味着比赛或教练)的人员名单。活跃的定义是他们要么是教练,要么是运动员,要么是教练和运动员。
person 表格包含( id , name , height ) 运动员表将是( id , sport ) 指导表格为( id , sport )
我创造了3个内部联盟,告诉我谁既是教练又是运动员,他只是一名教练而且只是一名运动员。
这是通过内部联接完成的。
例如,
1)谁既是教练又是运动员
select
person.id,
person.name,
coach.sport as 'Coaches and plays this sport'
from coach
inner join athlete
on coach.id = athlete.id
and coach.sport = athlete.sport
inner join person
on athlete.id = person.id
这会列出一个每个教练和参加同一项运动的人的名单。
2)为了找出谁只是教练运动,我使用了如下的内部联接:
select
person.id,
person.name,
coach.sport as 'Coaches this sport'
from coach
inner join person
on coach.id = person.id
3)然后找出谁只参加体育运动,我有同样的想法2)但只是调整了一下
select
person.id,
person.name,
athlete.sport as 'Plays this sport'
from athlete
inner join person
on athlete.id = person.id
最终结果是我现在得到了: 1)同时参加和训练相同运动的人 2)指导运动的人 3)参加体育运动的人
我想知道的是如何查找至少参加3项不同运动的人员名单?我无法弄明白,因为如果有人在表1中扮演和教练类似曲棍球的运动,那么我不想在表2和表3中计算它们。
我尝试使用这3个内部联接来创建一个大型连接表,以便我可以选择不同的值,但它不起作用。
是否有更简单的方法可以在不进行子查询的情况下进行此操作?
答案 0 :(得分:1)
我想知道的是如何查找播放/的人员列表 教练至少3种不同的运动?我无法弄明白,因为如果 有人在表1中扮演和教练像曲棍球这样的运动,然后我就不会 想要在表2和表3中统计它们。
你可以做这样的事情
select p.id,min(p.name) name
from
person p inner join
(
select id,sport from athlete
union
select id,sport from coach
)
ca
on ca.id=p.id
group by p.id
having count(ca.sport)>2
答案 1 :(得分:0)
CREATE TABLE #person (Id INT, Name VARCHAR(50));
CREATE TABLE #athlete (Id INT, Sport VARCHAR(50));
CREATE TABLE #coach (Id INT, Sport VARCHAR(50));
INSERT INTO #person (Id, Name) VALUES(1, 'Bob');
INSERT INTO #person (Id, Name) VALUES(2, 'Carol');
INSERT INTO #person (Id, Name) VALUES(2, 'Sam');
INSERT INTO #athlete (Id, Sport) VALUES(1, 'Golf');
INSERT INTO #athlete (Id, Sport) VALUES(1, 'Football');
INSERT INTO #coach (Id, Sport) VALUES(1, 'Tennis');
INSERT INTO #athlete (Id, Sport) VALUES(2, 'Tennis');
INSERT INTO #coach (Id, Sport) VALUES(2, 'Tennis');
INSERT INTO #athlete (Id, Sport) VALUES(2, 'Swimming');
-- so Bob has 3 sports, Carol has only 2 (she both coaches and plays Tennis)
SELECT p.Id, p.Name
FROM
(
SELECT Id, Sport
FROM #athlete
UNION -- this has an implicit "distinct"
SELECT Id, Sport
FROM #coach
) a
INNER JOIN #person p ON a.Id = p.Id
GROUP BY p.Id, p.Name
HAVING COUNT(*) >= 3
-- returns 1, Bob
答案 2 :(得分:0)
我创建了一个包含一些测试数据的SQL - 应该适用于您的情况:
将两个结果连接到子选项UNION
:
UNION
将仅返回非重复值。因此,每项运动都只计算一次。
最后,只需按person.Person_id和person.name对结果集进行分组。
由于HAVING
条款,只有3人或以上运动的人才会被退回 -
CREATE TABLE person
(
Person_id int
,name varchar(50)
,height int
)
CREATE TABLE coach
(
id int
,sport varchar(50)
)
CREATE TABLE athlete
(
id int
,sport varchar(50)
)
INSERT INTO person VALUES
(1,'John', 130),
(2,'Jack', 150),
(3,'William', 170),
(4,'Averel', 190),
(5,'Lucky Luke', 180),
(6,'Jolly Jumper', 250),
(7,'Rantanplan ', 90)
INSERT INTO coach VALUES
(1,'Football'),
(1,'Hockey'),
(1,'Skiing'),
(2,'Tennis'),
(2,'Curling'),
(4,'Tennis'),
(5,'Volleyball')
INSERT INTO athlete VALUES
(1,'Football'),
(1,'Hockey'),
(2,'Tennis'),
(2,'Volleyball'),
(2,'Hockey'),
(4,'Tennis'),
(5,'Volleyball'),
(3,'Tennis'),
(6,'Volleyball'),
(6,'Tennis'),
(6,'Hockey'),
(6,'Football'),
(6,'Cricket')
SELECT person.Person_id
,person.name
FROM person
INNER JOIN (
SELECT id
,sport
FROM athlete
UNION
SELECT id
,sport
FROM coach
) sports
ON sports.id = person.Person_id
GROUP BY person.Person_id
,person.name
HAVING COUNT(*) >= 3
ORDER BY Person_id
答案 3 :(得分:0)
教练&运动员,即教练或运动员,与您的答案相关。这是union(一个或另一个中的行),而不是(内部)连接一个和另一个中的行)。 (虽然外部联接涉及一个联盟,所以在这里使用它有一种复杂的方式。)但是通过联合只有教练,只有运动员& amp;教练运动员。
惯用语是分组&算上运动员联盟教练。
select id
from (select * from Athletes union select * from Coaches) as u
group by id
having COUNT(*) >= 3
或者,你需要那些教练或参加第一项运动和教练或参加第二项运动和教练或参加第三项运动的人的ids,这些运动都是不同的。
with u as (select * from Athletes union select * from Coaches)
select u1.id
from u u1
join u u2 on u1.id = u2.id
join u u3 on u2.id = u3.id
where u1.sport <> u2.sport and u2.sport <> u3.sport and u1.sport <> u3.sport
如果你想要名字,你可以加入People。
从人类可读的描述中构造SQL查询是否有任何经验法则?](https://stackoverflow.com/a/33952141/3404097)