我有一张桌子,其中包含保龄球中心球员的分数。每行都有一些关于哪个玩家击败游戏,玩哪个联赛,日期,单个游戏得分,车道号等的数据。
我想要做的就是让每一条赛道上的最佳系列赛(三场比赛)得分(以及在哪个联赛和哪个日期...基本上整排)。
到目前为止我所拥有的是
SELECT PlayerID, LaneNumber, MAX(Series)
FROM (SELECT Season, LeagueName, LaneNumber, WeekNumber, PlayerID, Date, SUM(Score) AS Series
FROM Scores
GROUP BY Season, LeagueName, WeekNumber, PlayerID)
GROUP BY LaneNumber
这是有效的,因为我为每一条车道获得了最好的三个游戏,这实际上就是我想要的,但是包含PlayerID的另一个字段实际上并不正确。
在我的表格中,24号车道(从SUM(得分)和GROUP BY赛季,LeagueName,WeekNumber,PlayerID获得)的最高分为848,由玩家ID为36的玩家进行。
我得到的是24号通道848(这是正确的),但PlayedID返回是3166.同样的事情发生在每一条车道上。 (因为,我得到了明显错误的PlayerID。如果我在第一个选择中有其他列,那么它们也是错误的)
答案 0 :(得分:3)
您违反了GROUP BY
的语义。
使用GROUP BY
时,它仅对您按(例如SELECT
)分组的LaneNumber
列和其他列的汇总函数(例如MAX(Series)
)有意义。选择其他任何内容(在您的情况下为PlayerID
)没有意义,因为您没有在共享相同LaneNumber
的人中指定您想要的玩家ID。< / p>
遗憾的是,默认情况下,MySql会在不报告错误的情况下执行此操作,并且它将返回它为违规列选择的任何值。在您的情况下,这意味着您将获得在指定分组中包含的玩家ID“随机”选择。
您也在内部查询中执行此操作,您可以在其中选择LaneNumber
,WeekNumber
和Date
。
<强>解决方案强>
需要重写查询,但首先需要仔细指定要获得的结果。您是否想要每个系列(以及任何通道)的最佳播放器和相关数据?对于每个系列和车道分开?这个问题的答案将决定GROUP BY
所需的内容,以及查询的内容。
答案 1 :(得分:2)
请看这里:http://dev.mysql.com/doc/refman/5.0/en/example-maximum-column-group-row.html
尝试在一个查询中完成所有操作可能会变得混乱,但基本上,您希望像以前一样生成系列数据:
SELECT Season, LeagueName, LaneNumber, WeekNumber, PlayerID, Date, SUM(Score) AS Series
FROM Scores
GROUP BY Season, LeagueName, WeekNumber, PlayerID
然后,您需要添加一个子句:WHERE Series=
,然后要获得正确的值,而不是从此表中获取max系列值,您需要执行另一个选择,获得最大值(系列) )其中LaneNumber在两个表中都是相同的。我会为你编写代码,但我对MySQL的能力不够自信!
答案 2 :(得分:2)
如@Jon所述,您需要删除那些不适用于特定人的元素。然后,由于@Ord有最接近的样本,最好将结果预先查询到一个单独的表中(不是临时的,因为MySQL会在第二个查询中尝试从自联接中查询自身时阻塞它)。 / p>
所以,对我来说(几年前曾经是联盟投球手),而且你的内容遍及所有联赛,同一时间的同一条赛道永远不会有两个不同的联赛,但是,整整一个晚上,你可以有不同的联赛开始不同的时间...例如6-8:30,8:45-11 ...所以联盟和日期的分组将起作用。但是,您需要将播放器作为组的一部分来获取它们各自的SUM()值。
为了帮助澄清答案,我假设我有以下数据。这些数据仅代表单个车道,一周,一个赛季,但每个联赛有两个联赛和3名球员(仅用于显示结果和限制内容)
League Player Score
L1 1 223
L1 1 218
L1 1 204
L1 2 187
L1 2 201
L1 2 189
L1 3 148
L1 3 152
L1 3 158
L2 4 189
L2 4 195
L2 4 192
L2 5 182
L2 5 199
L2 5 209
L2 6 228
L2 6 234
L2 6 218
CREATE TABLE SeriesScores2
SELECT
Season,
LeagueName,
LaneNumber,
WeekNumber,
PlayerID,
SUM(Score) AS Series
FROM
Scores
GROUP BY
Season,
LeagueName,
LaneNumber,
WeekNumber,
PlayerID;
第一个查询(上面)将创建将为所有玩家创建所有星期,所有联盟等的系列。假设现在我已经添加了共同的季节,车道,周也
Season League Lane Week Player Series
1 L1 1 1 1 645
1 L1 1 1 2 577
1 L1 1 1 3 458
1 L2 1 1 4 576
1 L2 1 1 5 590
1 L2 1 1 6 680
这为我们提供了确定max()的前提,否则我们必须在自身内部和外层重复查询,使其比预先聚合更复杂。
现在,上面的永久表(可以在获得结果后删除),查询FIRST(PreQuery)获得最高分PER PERAGUE PER LANE ...例如:男子联赛通常会有更高的系列赛分数比女性......与不同年龄组相似。所以,男子联赛第1的最高分和女子联赛第1的最高分等等。最高分通常在整个赛季的单周确定,而不是每周最高系列赛。
现在,PreQuery“ss”的别名就在赛季,联赛,车道和最大系列赛上。一旦知道了这一点,就自行参加系列赛得分,以获得该赛道上得分最高的WHO DID并拉出谁及其发生的那一周
select
ss.season,
ss.leaguename,
ss.lanenumber,
ss.highestSeries,
ss2.PlayerID,
ss2.WeekNumber
from
( select season, leaguename, lanenumber, max( series ) highestSeries
from SeriesScores2
group by season, leaguename, lanenumber ) ss
join SeriesScores2 ss2
on ss.Season = ss2.Season
and ss.LeagueName = ss2.LeagueName
and ss.LaneNumber = ss2.LaneNumber
and ss.HighestSeries = ss2.Series
现在,从上面的查询...让我们分解它。如果我们采取内在的“ss”预先查询
( select season, leaguename, lanenumber, max( series ) highestSeries
from SeriesScores2
group by season, leaguename, lanenumber ) ss
我们将获得每个联赛的最高得分(例如:男子联赛与女子联赛同一周,同一夜,同一车道,我们发现(下方),仅仅是最大值,但没有世界卫生组织或什么周,只是最高级别的系列赛,不论周或人。所以这成为JOIN的基础回到预先汇总的表“SeriesScores2”,但在这里,我们有最高的系列分数,以确保我们找到正确的人
Season League Lane HighestSeries
1 L1 1 645
1 L2 1 680
To refresh preaggregation
Season League Lane Week Player Series
1 L1 1 1 1 645 <-- Join finds THIS entry League 1
1 L1 1 1 2 577
1 L1 1 1 3 458
1 L2 1 1 4 576
1 L2 1 1 5 590
1 L2 1 1 6 680 <-- Join finds THIS entry League 2
所以,我的原始查询确实有效,因为我在发布前测试了它们。除非专栏名称不正确或其他什么,否则我不知道你对你的打嗝。至于“日期”栏目,我并不特别在意,因为你有可用的周数,这对应于保龄球周,并且无论如何都是1:1的关系。可以将日期列添加到预聚合SeriesScores2中,并在获取人员ID和周时拉出。 (除非一个联盟在同一个星期的多个晚上投球,然后你需要明确的日期)。
希望这能澄清您的问题/意见。
答案 3 :(得分:1)
好的,尝试实际编写我想到的MySQL代码(我无法抗拒......):
CREATE TEMPORARY TABLE SeriesScores
SELECT Season, LeagueName, LaneNumber, WeekNumber, PlayerID, SUM(Score) AS Series
FROM Scores
GROUP BY Season, LeagueName, WeekNumber, PlayerID;
这个位只会获得每个系列的分数,正如您在自己的MySQL代码中指定的那样。唯一不同的是我没有选择日期,因为我们不按它分组,它的值将是随机的。然后:
SELECT PlayerID, LaneNumber, Series
FROM SeriesScores s1
WHERE Series=(SELECT MAX(s2.Series)
FROM SeriesScores s2
WHERE s1.LaneNumber = s2.LaneNumber);
这一位只是从SeriesScores中选择你需要的东西,并且只考虑系列分数是那条泳道最大值的行。
这对你有用吗?