簡體   English   中英

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

[英]max in one column and min in another column

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

+---+---+
| A | B |
+---+---+
| 2 | 1 |
| 5 | 1 | 
| 6 | 1 |
| 1 | 2 |
| 5 | 2 |
| 0 | 2 |
| 2 | 3 |
| 7 | 3 |
| 4 | 3 |
| 5 | 4 |
+---+---+

我想從B的每個組中獲得最大的A值。但是,我不想包含B中的數字較高但A值小於上一個值的結果。 我知道這在語言上沒有意義,但這是我希望最終結果看起來像的樣子:

+---+---+
| A | B |
+---+---+
| 6 | 1 |
| 7 | 3 |
+---+---+

到目前為止,我有類似“從表1中按b選擇max(a),b”之類的東西,但這並沒有忽略B較高但max 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

我已經測試過了:-)

編輯:額外的見解

我想分享一些我如何提出這類解決方案的見解; 因為我認為對於人們來說,開始“思考集合”很重要……這是我閱讀過的有關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 |
+------+------+------------+------------+

然后,該集合實際上是在內存中創建的(完全連接的版本永遠不會完全存在於內存中,因為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 |
+------+------+------------+------------+

然后,當然,它會將結果從那里匯總為最終形式,僅從原始行中選擇A和B。

一個更簡單的解決方案是使用變量存儲上一行的a值,並在每次迭代時進行比較。 這也說明了b列中可能有空格的情況,其中數字並非完全按完美的順序排列:

SELECT @val:=a.a AS a, a.b
FROM
(
  SELECT MAX(a) AS a, b
  FROM tbl
  GROUP BY b
) a
WHERE a.a > IFNULL(@val,-1)
Select Z.a, Z.b from
(select a, b, rank() over (order by b) as ranker from (select max(a) a, b  from table1 group by b) Y) Z left join
(select a, b, rank() over (order by b) as ranker from (select max(a) a, b  from table1 group by b) Y1) Z1
on Z.ranker = Z1.ranker + 1
where Z.a > isnull(Z1.a, -100000)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM