我的查询目前是:
SELECT x, MAX(z) AS mz, y FROM my_table GROUP BY x
列x和mz按预期返回,但最后一列y与其他两列不匹配。换句话说,我希望“y”列与mz列匹配,就像x列当前一样。我该怎么做呢?
更新:对不起,问题不是很清楚。我想执行以下查询:
SELECT * FROM(SELECT x,MAX(z)AS mz FROM my_table GROUP BY x)一个权利 JOIN(选择y,MAX(z)AS mz FROM my_table GROUP BY y)b ON a.mz = b.mz
而不必使用3个SELECT语句(也许这不是什么大问题,但对我来说这似乎是一个低效的查询。但我在sql查询时很新,所以我不知道。)
更新#2:让我说我的表看起来像这样:
-------------------
| x | y | z |
-------------------
| 45 | h | 3 |
| 23 | c | 5 |
| 45 | e | 9 |
| 23 | b | 12 |
| 45 | x | 36 |
| 33 | s | 44 |
| 33 | p | 78 |
-------------------
我想返回以下内容:
-------------------
| x | y | z |
-------------------
| 23 | b | 12 |
| 45 | x | 36 |
| 33 | p | 78 |
-------------------
答案 0 :(得分:3)
你可以做到
select s.x, s.mz, stuff.y
from (select x, max(z) as mz from stuff group by x) s
left join stuff on stuff.x = s.x and stuff.z = s.mz;
答案 1 :(得分:2)
如果我理解你的话,你希望得到x和y的所有组合的最大Z.
如果是,您的陈述应为:
SELECT x, y, MAX(z) AS mz FROM my_table GROUP BY x,y
答案 2 :(得分:1)
我认为你的问题仍然有点朦胧。我想你说的是:
对于您的表格,您有一些值(X,Y和Z)。对于每个X,您可以有多个Y和Z,但是对于每个X,您想要获得Y的精确值,该值对应于该X的最高Z.
我们来举个例子。让我们假设这是一张表,记录员工每年生病的天数:
员工,年,天病 约翰,1999年,1 约翰,2000年,3 约翰,2001年,8
你想知道,对于每个员工来说,他们哪一年生病最多。
Select Employee, Year, DaysSick
From SickDays SD
Join (Select Employee, MAX(DaysSick) DaysSick
From SickDays
Group By Employee) MSD ON SD.Employee = MSD.Employee
And SD.DaysSick = MSD.DaysSick
这消除了您的一个选择。可能有一种方法可以使用Oracle中的分析函数来获取相同的数据,但性能不会好得多。至少,你需要一次通过才能找出MAX和第二次获取(希望在索引列上)来检索完整的数据集。
答案 3 :(得分:1)
我知道你想找到与它们的最大值(z)相同的对(x,y)。它需要做不同的选择以找到每个的最大值(z)....但也许有一些黑客或奇怪的想法来做它。
无论如何做你的方式并不难看,因为你是两次完全扫描桌子,然后加入部分结果(运气不会那么多)。所以它的时间将与表格成线性比例(如果x和y没有那么多不同的值):
总成本= X +分组成本Y +分组成本如果x和y是离散的,则成本不是很高。
你正在寻找max's,所以你必须完全扫描桌子,所以它是线性时间,以免。
这就是我的观点:你距离最佳状态还不远:)
答案 4 :(得分:1)
未定义在您的示例中使用group by选择“y”的结果。 MySQL将返回它扫描的第一行,但其他数据库可能会做一些完全不同的事情。如果要获取包含max(z)的行,则必须在子查询或连接中完成。 http://dev.mysql.com/doc/refman/5.0/en/example-maximum-column-group-row.html
select * from f f1 where z=(select max(z) from f f2 where f1.x=f2.x);
+------+------+------+
| x | y | z |
+------+------+------+
| 23 | b | 12 |
| 45 | x | 36 |
| 33 | p | 78 |
+------+------+------+
select * from f;
+------+------+------+
| x | y | z |
+------+------+------+
| 45 | h | 3 |
| 23 | c | 5 |
| 45 | e | 9 |
| 23 | b | 12 |
| 45 | x | 36 |
| 33 | s | 44 |
| 33 | p | 78 |
+------+------+------+