如何获得一个完全列出组成员的组?
How to get a group with exactly the group members listed?
一支足球队有 1 名或多名球员。一名球员属于一支或多支足球队。我有一份球员名单:'Bob', 'James', 'Sam'
我想知道哪支球队有这些球员。所以结果将是 Red Team
,因为 Red Team
是唯一一支完全 'Bob', 'James', 'Sam'
的队伍。请保留我拥有的所有连接。我知道您可以在技术上在 members
table 中完成所有操作,但为了简单起见,我只是这样构建的。
CREATE TABLE teams(
name VARCHAR(25) PRIMARY KEY
);
CREATE TABLE players(
name VARCHAR(25) PRIMARY KEY
);
CREATE TABLE members(
team_name VARCHAR(25) NOT NULL,
player_name VARCHAR(25) NOT NULL,
CONSTRAINT FK_team_name FOREIGN KEY (team_name) REFERENCES teams(name),
CONSTRAINT FK_player_name FOREIGN KEY (player_name) REFERENCES players(name)
);
INSERT INTO teams(name) VALUES ('Blue Team');
INSERT INTO teams(name) VALUES ('Red Team');
INSERT INTO teams(name) VALUES ('Green Team');
INSERT INTO teams(name) VALUES ('Purple Team');
INSERT INTO players(name) VALUES ('Bob');
INSERT INTO players(name) VALUES ('Sarah');
INSERT INTO players(name) VALUES ('James');
INSERT INTO players(name) VALUES ('Mike');
INSERT INTO players(name) VALUES ('Sam');
INSERT INTO members(team_name, player_name) VALUES ('Blue Team', 'Bob');
INSERT INTO members(team_name, player_name) VALUES ('Green Team', 'Bob');
INSERT INTO members(team_name, player_name) VALUES ('Green Team', 'Sam');
INSERT INTO members(team_name, player_name) VALUES ('Green Team', 'James');
INSERT INTO members(team_name, player_name) VALUES ('Green Team', 'Sarah');
INSERT INTO members(team_name, player_name) VALUES ('Red Team', 'Bob');
INSERT INTO members(team_name, player_name) VALUES ('Red Team', 'Sam');
INSERT INTO members(team_name, player_name) VALUES ('Red Team', 'James');
INSERT INTO members(team_name, player_name) VALUES ('Purple Team', 'Mike');
INSERT INTO members(team_name, player_name) VALUES ('Purple Team', 'Sam');
我的SQL声明:
SELECT DISTINCT
t.name
FROM teams t
LEFT JOIN members m
ON t.name = m.team_name
LEFT JOIN players p
ON m.player_name = p.name
WHERE
m.player_name in ('Bob', 'James', 'Sam')
您可以使用聚合和 having
子句。如果您想要 恰好 那些成员,那么您可以在 having
子句中进行过滤。以下假设团队内成员不能重复:
SELECT t.name
FROM teams t JOIN
members m
ON t.name = m.team_name JOIN
players p
ON m.player_name = p.name
GROUP BY t.name
HAVING SUM(CASE WHEN m.player_name IN ('Bob', 'James', 'Sam') THEN 1 ELSE 0 END) = 3 AND
COUNT(*) = 3;
编辑:
另一种方法使用 LISTAGG()
:
SELECT t.name
FROM teams t JOIN
members m
ON t.name = m.team_name JOIN
players p
ON m.player_name = p.name
GROUP BY t.name
HAVING LISTAGG(m.player_name, ',') WITHIN GROUP (ORDER BY m.player_name) = 'Bob,James,Sam';
Here 是一个 db<>fiddle.
如果您只想传入一个参数,这会很方便。但是,名称必须按照正确的顺序进行比较。
一支足球队有 1 名或多名球员。一名球员属于一支或多支足球队。我有一份球员名单:'Bob', 'James', 'Sam'
我想知道哪支球队有这些球员。所以结果将是 Red Team
,因为 Red Team
是唯一一支完全 'Bob', 'James', 'Sam'
的队伍。请保留我拥有的所有连接。我知道您可以在技术上在 members
table 中完成所有操作,但为了简单起见,我只是这样构建的。
CREATE TABLE teams(
name VARCHAR(25) PRIMARY KEY
);
CREATE TABLE players(
name VARCHAR(25) PRIMARY KEY
);
CREATE TABLE members(
team_name VARCHAR(25) NOT NULL,
player_name VARCHAR(25) NOT NULL,
CONSTRAINT FK_team_name FOREIGN KEY (team_name) REFERENCES teams(name),
CONSTRAINT FK_player_name FOREIGN KEY (player_name) REFERENCES players(name)
);
INSERT INTO teams(name) VALUES ('Blue Team');
INSERT INTO teams(name) VALUES ('Red Team');
INSERT INTO teams(name) VALUES ('Green Team');
INSERT INTO teams(name) VALUES ('Purple Team');
INSERT INTO players(name) VALUES ('Bob');
INSERT INTO players(name) VALUES ('Sarah');
INSERT INTO players(name) VALUES ('James');
INSERT INTO players(name) VALUES ('Mike');
INSERT INTO players(name) VALUES ('Sam');
INSERT INTO members(team_name, player_name) VALUES ('Blue Team', 'Bob');
INSERT INTO members(team_name, player_name) VALUES ('Green Team', 'Bob');
INSERT INTO members(team_name, player_name) VALUES ('Green Team', 'Sam');
INSERT INTO members(team_name, player_name) VALUES ('Green Team', 'James');
INSERT INTO members(team_name, player_name) VALUES ('Green Team', 'Sarah');
INSERT INTO members(team_name, player_name) VALUES ('Red Team', 'Bob');
INSERT INTO members(team_name, player_name) VALUES ('Red Team', 'Sam');
INSERT INTO members(team_name, player_name) VALUES ('Red Team', 'James');
INSERT INTO members(team_name, player_name) VALUES ('Purple Team', 'Mike');
INSERT INTO members(team_name, player_name) VALUES ('Purple Team', 'Sam');
我的SQL声明:
SELECT DISTINCT
t.name
FROM teams t
LEFT JOIN members m
ON t.name = m.team_name
LEFT JOIN players p
ON m.player_name = p.name
WHERE
m.player_name in ('Bob', 'James', 'Sam')
您可以使用聚合和 having
子句。如果您想要 恰好 那些成员,那么您可以在 having
子句中进行过滤。以下假设团队内成员不能重复:
SELECT t.name
FROM teams t JOIN
members m
ON t.name = m.team_name JOIN
players p
ON m.player_name = p.name
GROUP BY t.name
HAVING SUM(CASE WHEN m.player_name IN ('Bob', 'James', 'Sam') THEN 1 ELSE 0 END) = 3 AND
COUNT(*) = 3;
编辑:
另一种方法使用 LISTAGG()
:
SELECT t.name
FROM teams t JOIN
members m
ON t.name = m.team_name JOIN
players p
ON m.player_name = p.name
GROUP BY t.name
HAVING LISTAGG(m.player_name, ',') WITHIN GROUP (ORDER BY m.player_name) = 'Bob,James,Sam';
Here 是一个 db<>fiddle.
如果您只想传入一个参数,这会很方便。但是,名称必须按照正确的顺序进行比较。