簡體   English   中英

Sql查詢最大值,分組依據

[英]Sql query max, group by

在此處輸入圖片說明

我正在嘗試通過 class_id、student_id、teacher_id 將所有學生分組,所以我的意思是這個:

Select id,class_id, student_id,teacher_id, max(active)
                                 FROM student_classes
                                  GROUP BY class_id, student_id, teacher_id

但這就是我得到的在此處輸入圖片說明

其實我想要的結果是:

114   137  1  47  1
108   138  2  49  0
 113  197  3  47  1

所以基本上問題出在第三行。 我得到的不是 id = 113,而是 ID = 111。 在這種情況下我該怎么辦? 你能幫我查詢嗎

如評論中所述,MySQL 允許違反 SQL 標准的內容,讓您在包含group by的查詢的選擇列表中包含非聚合列(在本例中為id )。 據我所知,它會在每個分組中任意選擇一行並顯示該行的id值。

如果您對要查看的id值有特定的規則,則需要在查詢中表達出來。

順便說一下,您想要的輸出似乎有多個拼寫錯誤(例如 197,它根本沒有出現在您的數據中)。

從您的評論(您應該將其編輯為原始問題)和您想要的輸出,我認為您想要的id列規則是:

  • 如果組中有 active=1 的任何行,請從這些行中選擇最大的 id 值
  • 如果組中的所有行都具有 active=0,則選擇最小 id 值。 (你沒有具體說這個;我假設它是基於你想要的輸出的第二行上 108 的存在。)

我認為這個查詢會產生這些結果。 (並且還消除了非標准的 MySQL 行為。)

  SELECT
   COALESCE(
        MAX(CASE WHEN active=1 THEN id ELSE NULL END),
        MIN(id)
      ) AS some_id
   class_id, student_id, teacher_id, max(active)
  FROM student_classes
  GROUP BY class_id, student_id, teacher_id

您實際上並不想要聚合,而是選擇特定的行。 選擇一行的規則是:每個class_id, student_id, teacher_id獲得最大active的一個,在平局的情況下獲得最低的id 這是行的排名。

從 MySQL 8 開始,您可以使用像ROW_NUMBER這樣的窗口函數來對行進行排名:

select *
from
(
  select
    sc.*,
    row_number() over (partition by class_id, student_id, teacher_id
                       order by active desc, id) as rn
  from student_classes sc
) with_wanted_id
where rn = 1;

在舊版本中,您可以使用NOT EXISTS來排除存在更好行的行:

select *
from student_classes sc1
where not exists
(
  select null
  from student_classes sc2
  where sc2.class_id = sc1.class_id
    and sc2.student_id = sc1.student_id
    and sc2.teacher_id = sc1.teacher_id
    and
    (
      sc2.active > sc1.active
      or
      (sc2.active = sc1.active and sc2.id < sc1.id)
    )
);

MySQL 5.5、5.6 版按您的編碼工作。 但實際上並不正確。 對於 5.7 及更高版本,它會拋出錯誤。 錯誤將類似於“SELECT 列表不在 GROUP BY 子句中並且包含非聚合列 'student_classes.id'...”
因此,您的數據庫版本似乎很舊,也許此代碼應該可以按您的意願工作

select 
    ---------
    min(x.id) as id, 
    ---------
    x.class_id, 
    x.student_id, 
    x.active
from student_classes x
 inner join (select 
                class_id, 
                student_id, 
                teacher_id, 
                ---------
                max(active) max_active 
                ---------
              from student_classes x 
              group by class_id, student_id, teacher_id
            )  y
    on x.class_id = y.class_id and 
        x.student_id = y.student_id and 
        x.teacher_id = y.teacher_id and 
        x.active = y.max_active
 group by x.class_id, x.student_id, x.active
 order by id, class_id, student_id
;

暫無
暫無

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

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