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查询中.
此技术将表与其自身的聚合版本连接起来,但是连接偏移一,因此每一行都与前一个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.
| 归档时间: |
|
| 查看次数: |
1250 次 |
| 最近记录: |