Mysql 如何从使用聚合函数分组的多个表中返回多个列
我有以下三个表格:Mysql 如何从使用聚合函数分组的多个表中返回多个列,mysql,sql,Mysql,Sql,我有以下三个表格: 1. Results table (containing performances) 2. Athletes table (containing athlete ids and names) 3. Events table (containing event ids and eventNames) Results Table (sample) +----------+-----------+---------+----------+----------+------+---
1. Results table (containing performances)
2. Athletes table (containing athlete ids and names)
3. Events table (containing event ids and eventNames)
Results Table (sample)
+----------+-----------+---------+----------+----------+------+------------+-----------+--------+----------+---------+-----------------------+--------+----------------+------------+
| resultID | athleteID | eventID | ageGroup | time | wind | distHeight | implement | record | centreID | placing | competition | in_out | venue | date |
+----------+-----------+---------+----------+----------+------+------------+-----------+--------+----------+---------+-----------------------+--------+----------------+------------+
| 203 | 503262 | 1 | MS | 00010.83 | 5.2 | | | D | AKL | 3 | IAAF Challenge | out | Arles FRA | 2008-06-07 |
| 201 | 515092 | 1 | MS | 00011.06 | 3.2 | | | | CAN | 6h1 | Winter Series #3 | out | Gold Coast AUS | 2008-06-15 |
| 298 | 503262 | 1 | MS | 00011.26 | -1.0 | | | D | AKL | 4 | TNT - Fortuna | out | Kladno CZE | 2008-06-18 |
| 202 | 515092 | 2 | MS | 00022.69 | 0.6 | | | | CAN | 4h1 | Winter Series #3 | out | Gold Coast AUS | 2008-06-15 |
| 380 | 504550 | 2 | MS | 00022.22 | 0.9 | | | | AKL | 6rA | Int. Meeting Nivelles | out | Nivelles BEL | 2008-06-28 |
| 381 | 504613 | 2 | MS | 00021.28 | 0.9 | | | | AKL | 2rA | Int. Meeting Nivelles | out | Nivelles BEL | 2008-06-28 |
| 3 | 518131 | 33 | MS | | | 077.91 | 800gm | | WBP | 1Q | Good Luck Beijing | out | Beijing CHN | 2008-05-22 |
| 4 | 518131 | 33 | MS | | | 079.61 | 800gm | | WBP | 1 | Good Luck Beijing | out | Beijing CHN | 2008-05-23 |
| 144 | 518131 | 33 | MS | | | 080.51 | 800gm | | WBP | 1 | Chinese Taipei Int | out | Taiwan TPE | 2008-06-01 |
+----------+-----------+---------+----------+----------+------+------------+-----------+--------+----------+---------+-----------------------+--------+----------------+------------+
Event Table (sample)
+---------+---------------+
| eventID | eventName |
+---------+---------------+
| 1 | 100m |
| 2 | 200m |
| 33 | Javelin Throw |
+---------+---------------+
Athlete Table (sample)
+-----------+----------+-----------+--------+------------+--------+
| athleteID | nameLast | nameFirst | gender | DOB | clubID |
+-----------+----------+-----------+--------+------------+--------+
| 503262 | Lambert | Ben | M | 2003-12-04 | 233 |
| 504613 | Abba | Eric | M | 1991-11-03 | 20 |
| 518131 | Abbiss | Hugh | M | 1992-04-03 | 57 |
+-----------+----------+-----------+--------+------------+--------+
我需要从结果表中分别返回每个比赛项目的mintime和每个跳跃/投掷项目的maxdistance,以及相应的运动员姓名和项目名称
我曾尝试按照MySql 5.7的建议,将所选项目包括在“groupby”列表中,但最终返回了数千行
我有一个在MySql 5.7之前运行的查询
SELECT events.eventID, events.eventName, results.ageGroup, results.athleteID, MIN(results.time) AS time, MAX(results.distHeight) as distHeight, DATE_FORMAT(results.date, '%d %b %Y') as date, athletes.nameFirst, athletes.nameLast, DATE_FORMAT(athletes.DOB, '%d %b %Y') as format_DOB
FROM (
SELECT * FROM results
WHERE results.ageGroup = 'MS'
AND YEAR(results.date) = '2019'
AND results.wind < 2.1
AND results.wind != 'nwr'
ORDER BY results.time ASC, results.distHeight DESC, results.date ASC
) as results
INNER JOIN athletes ON results.athleteID = athletes.athleteID
INNER JOIN events ON results.eventID = events.eventID
GROUP BY results.eventID
ORDER BY events.eventID ASC
欢迎您提供任何帮助或建议……您应该在主查询中加入子查询,以获得更好的性能
select events.eventID
, events.eventName
, results.ageGroup
, results.athleteID
, t.time
, t.distHeight
, DATE_FORMAT(results.date, '%d %b %Y') as date
, athletes.nameFirst
, athletes.nameLast
, DATE_FORMAT(athletes.DOB, '%d %b %Y') as format_DOB
FROM events
INNER JOIN result ON results.eventID = events.eventID
INNER JOIN athletes ON results.athleteID = athletes.athleteID
INNER JOIN (
SELECT events.eventName
, results.ageGroup
, MIN(results.time) AS time
, MAX(results.distHeight) as distHeight
FROM events
INNER JOIN result ON results.eventID = events.eventID
WHERE results.ageGroup = 'MS'
AND YEAR(results.date) = '2019'
AND results.wind < 2.1
AND results.wind != 'nwr'
GROUP BY events.eventName, results.ageGroup
) t ON t.eventName = event.eventName
AND t.ageGroup = result.ageGroup
AND ( t.time = result.time OR t.distHeight = result.distHeight)
ORDER BY results.time ASC, results.distHeight DESC, results.date ASC
也许这就是子查询将表绘制在一起并计算出哪个结果与最小值或最大值匹配的地方
select eeventname,
case when mintime is not null then mintime
else maxdistheight
end as result,
anamelast
from
(
select r.athleteid rathelteid,r.eventID reventid,r.agegroup ragegroup,
r.time,r.distheight,
e.eventid eeventid,e.eventname eeventname ,
a.athleteid aathleteid,a.namelast anamelast,
(select min(time) from results r1 where r1.eventID = r.eventid and time is not null) mintime,
(select max(distheight) from results r1 where r1.eventID = r.eventid and time is null) maxdistheight
from results r
join events e on e.eventid = r.eventid
left join athlete a on a.athleteid = r.athleteid
having mintime = r.time or r.distHeight = maxdistheight
) s;
+---------------+--------+-----------+
| eeventname | result | anamelast |
+---------------+--------+-----------+
| 100m | 10.83 | Lambert |
| 200m | 21.28 | Abba |
| Javelin Throw | 80.51 | Abbiss |
+---------------+--------+-----------+
3 rows in set (0.00 sec)
您应该测试这个绘图,并添加任何其他您需要的条件。我想出了这个最终奏效的方法-感谢您的帮助
SELECT events.eventID, events.eventName, results.ageGroup, results.athleteID, t.distHeight, t.time, DATE_FORMAT(results.date, '%d %b %Y') as date, athletes.nameFirst, athletes.nameLast, DATE_FORMAT(athletes.DOB, '%d %b %Y') as format_DOB, competition
FROM results
INNER JOIN events ON results.eventID = events.eventID
INNER JOIN athletes ON results.athleteID = athletes.athleteID
INNER JOIN (
SELECT events.eventID, results.athleteID, results.resultID, results.ageGroup, MIN(results.time) AS time, MAX(results.distHeight) as distHeight
FROM events
INNER JOIN results ON results.eventID = events.eventID
WHERE results.ageGroup = 'MS'
AND YEAR(results.date) = '2019'
GROUP BY events.eventID, time, distHeight
ORDER BY time ASC, distHeight DESC
) t ON t.resultID = results.resultID
AND t.eventID = results.eventID
AND ( t.time = results.time AND t.distHeight = results.distHeight)
WHERE YEAR(results.date) = '2019'
GROUP BY events.eventID, results.eventID
你能添加你的表定义和示例数据吗?我不确定当results.wind看起来是一个字符串,并且子查询中的order by毫无意义时,“results.wind<2.1”是如何工作的。“我有一个在MySql 5.7之前工作的查询”它可能运行,但可能不“工作”-运动员将无法确定一个事件的长度超过1结果和mintime与maxdistheight不在同一行。你的数据可能永远不会是这样-只有你知道..谢谢你的反馈。。。我添加了一些示例数据感谢代码示例-我尝试了这种方法,但它为每个事件返回了数千行而不是一行。我在我的原始问题中发布了一些示例数据表。。。可能会让事情更清楚@我很抱歉。。。我在join中错过了仅获取与较好记录匹配的行的条件。。答案更新…希望有用。谢谢!我试过了,但还是不走运。太多行了。我不是专家,所以我必须消化这一点,看看需要在哪里进行调整。概念是使用子查询来获得更好的结果,并将此结果与包含所有信息的ctable连接起来。。希望这个建议能帮上忙,再次感谢尝试了此解决方案,但数据库在运行时挂起。你认为我可以看的任何修改或选项。变成了一个相当棘手的问题。
SELECT events.eventID, events.eventName, results.ageGroup, results.athleteID, t.distHeight, t.time, DATE_FORMAT(results.date, '%d %b %Y') as date, athletes.nameFirst, athletes.nameLast, DATE_FORMAT(athletes.DOB, '%d %b %Y') as format_DOB, competition
FROM results
INNER JOIN events ON results.eventID = events.eventID
INNER JOIN athletes ON results.athleteID = athletes.athleteID
INNER JOIN (
SELECT events.eventID, results.athleteID, results.resultID, results.ageGroup, MIN(results.time) AS time, MAX(results.distHeight) as distHeight
FROM events
INNER JOIN results ON results.eventID = events.eventID
WHERE results.ageGroup = 'MS'
AND YEAR(results.date) = '2019'
GROUP BY events.eventID, time, distHeight
ORDER BY time ASC, distHeight DESC
) t ON t.resultID = results.resultID
AND t.eventID = results.eventID
AND ( t.time = results.time AND t.distHeight = results.distHeight)
WHERE YEAR(results.date) = '2019'
GROUP BY events.eventID, results.eventID