MySQL查询多列distinct加一个辅助列条件
MySQL query for multi-column distinct plus an ancillary column condition
想象一个跟踪游戏比赛的单位 table,其中每场比赛有三名参与者:一名攻击者、一名防守者和一名对玩家 1 和 2 之间的战斗结果下注的投注者。table包括每场比赛的选手姓名和投注者姓名,以及比赛日期、每位选手的得分、比赛场地和裁判姓名。我在下面包含了一些示例数据的 CREATE sql。
DROP TABLE IF EXISTS `game`;
CREATE TABLE `game` (
`game_date` text,
`player_1` text,
`player_2` text,
`bettor` text,
`p1_score` double DEFAULT NULL,
`p2_score` double DEFAULT NULL,
`result` double DEFAULT NULL,
`venue` text,
`referee` text
)
INSERT INTO `game` VALUES ('2020-04-05','Bob','Kelly','Kevin',100,78,0.2,'TS1','Richard'),('2020-03-06','Jim','Bob','Dave',100,97,1.2,'TS2','Mike'),('2020-02-05','Jim','Bob','Kevin',100,86,0.9,'TS2','Mike'),('2020-01-06','Kelly','Bob','Jim',100,92,1.3,'TS2','Richard'),('2019-12-07','Kelly','Bob','Jim',100,98,1.7,'TS1','Mike'),('2019-11-07','Kelly','Bob','Kevin',78,100,2.1,'TS2','Mike'),('2019-10-08','Kelly','Bob','Kevin',97,100,1.5,'TS1','Mike'),('2019-09-08','Kelly','Jim','Dave',86,100,2.4,'TS1','Richard'),('2019-08-09','Kelly','Jim','Dave',92,100,2.8,'TS2','Mike'),('2019-07-10','Kelly','Jim','Dave',98,100,2.2,'TS2','Mike'),('2019-06-10','Kelly','Jim','Dave',100,78,1.9,'TS2','Richard'),('2019-05-11','Sarah','Jim','Kevin',100,97,2.1,'TS1','Mike'),('2019-04-11','Sarah','Jim','Kevin',100,86,2.1,'TS2','Mike'),('2019-03-12','Sarah','Jim','Kevin',100,92,2.8,'TS1','Mike'),('2019-02-10','Sarah','Jim','Kevin',100,98,1.8,'TS1','Richard');
我需要查询 return 比赛参与者的每个独特组合的比赛信息...但仅限于三名参与者一起参加的第一场比赛,即最早的 game_date三人参加的比赛中
例如,如果 Bob 是 1 号玩家,Kelly 是 2 号玩家,而 Kevin 是下注者,这将构成一个独特的三人组。在数据中,这个三人组只有一个这样的配对,所以查询将为那个匹配 return 一行。
在 Sarah 作为玩家 1、Jim 作为玩家 2 和 Kevin 作为投注者的情况下,该三人组有四场比赛,因此查询将 return 仅提供最早比赛的信息,即一个 2/10/2019.
请注意,在样本数据中有两个与三人组 'Kelly'、'Bob'、'Jim' 的匹配项。还有另外两场与三人组的比赛 'Kelly'、'Jim'、'Bob'。这些是不一样的,因为 Bob 和 Jim 交换了位置,有玩家 2 和下注者。因此,查询将 return 一行对应它们中的每一个,即日期分别为“12/072019”和“08/09/2019”的匹配项。
使用 DISTINCT,我可以 return 列出所有独特的玩家分组。
SELECT DISTINCT player_1, player_2, bettor FROM games;
使用 GROUP BY,我可以return 该组参加的所有比赛的所有比赛信息。
SELECT * FROM games GROUP BY player_1, player_2, bettor;
但我不知道如何 return 所有游戏信息,但仅限于所有三名参与者一起玩并在游戏中扮演不同角色的最早游戏。
我已经尝试使用 MIN() 进行子查询 game_date,但这是失败的。我怀疑可能有一个 INNER JOIN 解决方案,但我还没有找到它。
非常感谢您提供的任何指导。
一种规范方法使用连接到子查询,该子查询标识每个三重奏的最早游戏:
SELECT g1.*
FROM games g1
INNER JOIN
(
SELECT player_1_name, player_2_name, player_3_name,
MIN(game_date) AS min_game_date
FROM games
GROUP BY player_1_name, player_2_name, player_3_name
) g2
ON g2.player_1_name = g1.player_1_name AND
g2.player_2_name = g1.player_2_name AND
g2.player_3_name = g1.player_3_name AND
g2.min_game_date = g1.game_date;
如果你是运行 MySQL 8+,那么ROW_NUMBER
解析函数提供了另一种选择:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY player_1_name, player_2_name,
player_3_name
ORDER BY game_date) rn
FROM games
)
SELECT *
FROM cte
WHERE rn = 1;
想象一个跟踪游戏比赛的单位 table,其中每场比赛有三名参与者:一名攻击者、一名防守者和一名对玩家 1 和 2 之间的战斗结果下注的投注者。table包括每场比赛的选手姓名和投注者姓名,以及比赛日期、每位选手的得分、比赛场地和裁判姓名。我在下面包含了一些示例数据的 CREATE sql。
DROP TABLE IF EXISTS `game`;
CREATE TABLE `game` (
`game_date` text,
`player_1` text,
`player_2` text,
`bettor` text,
`p1_score` double DEFAULT NULL,
`p2_score` double DEFAULT NULL,
`result` double DEFAULT NULL,
`venue` text,
`referee` text
)
INSERT INTO `game` VALUES ('2020-04-05','Bob','Kelly','Kevin',100,78,0.2,'TS1','Richard'),('2020-03-06','Jim','Bob','Dave',100,97,1.2,'TS2','Mike'),('2020-02-05','Jim','Bob','Kevin',100,86,0.9,'TS2','Mike'),('2020-01-06','Kelly','Bob','Jim',100,92,1.3,'TS2','Richard'),('2019-12-07','Kelly','Bob','Jim',100,98,1.7,'TS1','Mike'),('2019-11-07','Kelly','Bob','Kevin',78,100,2.1,'TS2','Mike'),('2019-10-08','Kelly','Bob','Kevin',97,100,1.5,'TS1','Mike'),('2019-09-08','Kelly','Jim','Dave',86,100,2.4,'TS1','Richard'),('2019-08-09','Kelly','Jim','Dave',92,100,2.8,'TS2','Mike'),('2019-07-10','Kelly','Jim','Dave',98,100,2.2,'TS2','Mike'),('2019-06-10','Kelly','Jim','Dave',100,78,1.9,'TS2','Richard'),('2019-05-11','Sarah','Jim','Kevin',100,97,2.1,'TS1','Mike'),('2019-04-11','Sarah','Jim','Kevin',100,86,2.1,'TS2','Mike'),('2019-03-12','Sarah','Jim','Kevin',100,92,2.8,'TS1','Mike'),('2019-02-10','Sarah','Jim','Kevin',100,98,1.8,'TS1','Richard');
我需要查询 return 比赛参与者的每个独特组合的比赛信息...但仅限于三名参与者一起参加的第一场比赛,即最早的 game_date三人参加的比赛中
例如,如果 Bob 是 1 号玩家,Kelly 是 2 号玩家,而 Kevin 是下注者,这将构成一个独特的三人组。在数据中,这个三人组只有一个这样的配对,所以查询将为那个匹配 return 一行。
在 Sarah 作为玩家 1、Jim 作为玩家 2 和 Kevin 作为投注者的情况下,该三人组有四场比赛,因此查询将 return 仅提供最早比赛的信息,即一个 2/10/2019.
请注意,在样本数据中有两个与三人组 'Kelly'、'Bob'、'Jim' 的匹配项。还有另外两场与三人组的比赛 'Kelly'、'Jim'、'Bob'。这些是不一样的,因为 Bob 和 Jim 交换了位置,有玩家 2 和下注者。因此,查询将 return 一行对应它们中的每一个,即日期分别为“12/072019”和“08/09/2019”的匹配项。
使用 DISTINCT,我可以 return 列出所有独特的玩家分组。
SELECT DISTINCT player_1, player_2, bettor FROM games;
使用 GROUP BY,我可以return 该组参加的所有比赛的所有比赛信息。
SELECT * FROM games GROUP BY player_1, player_2, bettor;
但我不知道如何 return 所有游戏信息,但仅限于所有三名参与者一起玩并在游戏中扮演不同角色的最早游戏。
我已经尝试使用 MIN() 进行子查询 game_date,但这是失败的。我怀疑可能有一个 INNER JOIN 解决方案,但我还没有找到它。
非常感谢您提供的任何指导。
一种规范方法使用连接到子查询,该子查询标识每个三重奏的最早游戏:
SELECT g1.*
FROM games g1
INNER JOIN
(
SELECT player_1_name, player_2_name, player_3_name,
MIN(game_date) AS min_game_date
FROM games
GROUP BY player_1_name, player_2_name, player_3_name
) g2
ON g2.player_1_name = g1.player_1_name AND
g2.player_2_name = g1.player_2_name AND
g2.player_3_name = g1.player_3_name AND
g2.min_game_date = g1.game_date;
如果你是运行 MySQL 8+,那么ROW_NUMBER
解析函数提供了另一种选择:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY player_1_name, player_2_name,
player_3_name
ORDER BY game_date) rn
FROM games
)
SELECT *
FROM cte
WHERE rn = 1;