一列中最大,另一列中最小

JYe*_*Yeh 0 mysql sql aggregate-functions

例如,如果列A和列B具有值:

+---+---+
| A | B |
+---+---+
| 2 | 1 |
| 5 | 1 | 
| 6 | 1 |
| 1 | 2 |
| 5 | 2 |
| 0 | 2 |
| 2 | 3 |
| 7 | 3 |
| 4 | 3 |
| 5 | 4 |
+---+---+
Run Code Online (Sandbox Code Playgroud)

从每组B中,我想得到A中最高的数字.但是,我不希望包含B中的数字较高但A值小于前一个的结果.我知道这在单词中没有意义,但这就是我想要的最终结果:

+---+---+
| A | B |
+---+---+
| 6 | 1 |
| 7 | 3 |
+---+---+
Run Code Online (Sandbox Code Playgroud)

到目前为止,我有类似"选择max(a),b来自table1 group by b"的内容,但这并没有省略B更高但最大A更小的那些.我知道我可以在PHP中仔细阅读该查询的结果并删除A值小于之前的A值的那些,但是如果可能的话我想把它全部放在mysql查询中.

Chr*_*hey 5

此技术将表与其自身的聚合版本连接起来,但是连接偏移一,因此每一行都与前一个B的MAX(A)值相关联.然后它匹配当前A大于其中任何一个的行,如果它没有找到任何行,则它不包括该行.然后我们汇总最终选择以获得您所追求的结果.

SELECT 
       MAX(source_row.A) as A, 
       source_row.B
  FROM ab as source_row
  LEFT JOIN (SELECT MAX(A) as A, B FROM ab GROUP BY B) AS one_back 
    ON one_back.B = source_row.B-1 
 WHERE (one_back.A IS NULL) 
    OR one_back.A < source_row.A
 GROUP BY B
Run Code Online (Sandbox Code Playgroud)

我测试了这个:-)

编辑:额外的洞察力

我想分享一下我如何提出这些解决方案的一些见解; 因为我认为人们开始"集中思考"很重要......这是我读过的有关JOINS的最佳建议,你需要设想你的查询正在使用的中间"集合".为了说明这一点,这里是中间"集合"的表示,它是该查询的关键部分; 它是表,因为它存在"加入"其自身的聚合版本.

+------+------+------------+------------+
| A    | B    | one_back.B | one_back.A |
+------+------+------------+------------+
|    2 |    1 |       NULL |       NULL |
|    5 |    1 |       NULL |       NULL |
|    6 |    1 |       NULL |       NULL |
|    1 |    2 |          1 |          6 |
|    5 |    2 |          1 |          6 |
|    0 |    2 |          1 |          6 |
|    2 |    3 |          2 |          5 |
|    7 |    3 |          2 |          5 |
|    4 |    3 |          2 |          5 |
|    5 |    4 |          3 |          7 |
+------+------+------------+------------+
Run Code Online (Sandbox Code Playgroud)

然后实际上是在内存中创建的集合(完整的连接版本永远不会完全在内存中,因为一旦知道它们不会"切断",MySQL就可以消除行:

+------+------+------------+------------+
| A    | B    | one_back.B | one_back.A |
+------+------+------------+------------+
|    2 |    1 |       NULL |       NULL |
|    5 |    1 |       NULL |       NULL |
|    6 |    1 |       NULL |       NULL |
|    7 |    3 |          2 |          5 |
+------+------+------------+------------+
Run Code Online (Sandbox Code Playgroud)

然后,当然,它将结果汇总到最终形式,从原始行中仅选择A和B.