如何使用“分组依据”和三列数据?

时间:2010-01-15 15:29:37

标签: sql mysql

我的查询目前是:

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 |
-------------------

5 个答案:

答案 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 | 
+------+------+------+