[SQL]查詢中如何同時orderBy A欄&groupBy B欄?

更新於 發佈於 閱讀時間約 9 分鐘

最近遇到一個需求是要更改排序的邏輯,原本想像應該很簡單,但實作起來卻出乎意料之外的麻煩!

原本的撈取邏輯:要取得某學員user的在特定區間的學習中的課程,而排序則依課程編號course_set_id由大至小排序。

需求:排序要改依照課程學習的時間來排序(由近至遠)

乍看之下,原以為只要調整orderby的欄位即可,但卻忽略了原本的groupbyorderby都是course_set_id,因此如果此時要改成time這個欄位來排序,groupby 就需要多加上time 這個欄位才符合SQL規範。但加上後卻會對原本的資料結果產生巨大影響。


原query查詢如下:

/**
* 學員進行中的課程
* @param array $conditions
* @param string $result_type
* @param int $per
* @return LengthAwarePaginator|int|null
*/
public function getCourseLearnLogByUser($conditions, $result_type = 'paginate', $per = 8)
{
$result = CourseLearnLog::with(['course.courseSet'])
->whereHas('course.courseSet', function ($query) use ($conditions) {
$query->available();
})
->where('user_id', $conditions['user_id'])
->whereBetween('time', [$conditions['start_date'], $conditions['end_date']])
->groupBy('course_set_id')
->select(DB::raw('course_set_id as idSubChannel'));

switch ($result_type) {
case 'paginate':
return $result
->orderby('course_set_id', 'desc')
->paginate($per);
case 'count':
return $result
->get()
->count();
default:
return null;
}
}


Example:

原始資料:

course_set_id = 1, time = 2021-01-01 10:00:00

course_set_id = 1, time = 2021-01-01 12:22:33

course_set_id = 2, time = 2021-01-01 11:00:00


原本groupby.course_set_id最後的資料只會有兩筆:

course_set_id = 1 雖然有兩筆資料,但會被group起來,因此最後結果會是unique比數的course_set_id


但如果groupby.course_set_id, groupby.time兩個欄位的話,最後會有三筆

course_set_id + time兩個不一樣就會成一組,因此原始資料的3筆都會列入


解決方案

為了解決這個情況,因此想到了使用SubQuery,將同一堂課程的閱讀時間取最大值,之後再與MainQuery做join(以course_set_id 做關聯),並在MainQuery針對SubQuery的max_time做降冪排序,就可以免除用groupby的方式來處理!


調整後的query查詢如下:

/**
* 學員進行中的課程
* @param array $conditions
* @param string $result_type
* @param int $per
* @return LengthAwarePaginator|int|null
*/
public function getCourseLearnLogByUser($conditions, $result_type = 'paginate', $per = 8)
{
// SubQuery取得每個 course_set_id 的最後閱讀時間
$timeSubQuery = CourseLearnLog::query()
->whereBetween('time', [$conditions['rule']['start_date'], $conditions['rule']['end_date']])
->where('user_id', $conditions['user_id'])
->groupBy('course_set_id')
->select('course_set_id', DB::raw('MAX(time) AS max_time'));

$result = CourseLearnLog::with(['course.courseSet'])
->whereHas('course.courseSet', function ($query) use ($conditions) {
$query->available();
})
->joinSub($timeSubQuery, 'max_times', function ($join) {
$join->on('course_learn_logs.course_set_id', '=', 'max_times.course_set_id');
})
->whereBetween('time', [$conditions['start_date'], $conditions['end_date']])
->where('course_learn_logs.user_id', $conditions['user_id'])
->groupBy('course_learn_logs.course_set_id')
->select(DB::raw('course_learn_logs.course_set_id as idSubChannel'));

switch ($result_type) {
case 'paginate':
return $result
->orderBy('max_times.max_time', 'desc')
->paginate($per);
case 'count':
return $result
->get()
->count();
default:
return null;
}
}


留言
avatar-img
留言分享你的想法!
avatar-img
欸! 是彼得的資料庫
65會員
46內容數
歡迎來到彼得的沙龍,在這裡,我將與你分享書籍精華的智慧、人際溝通的技巧、理財增值的秘訣,以及情緒管理的策略。不僅幫助你打好財務基礎,還能引領你在人生的每個環節中游刃有餘。如果你渴望成長,並追求更充實的生活,這裡就是你值得關注的空間。立即加入,與我一起探索成長的無限可能!
2025/04/01
什麼是 MCP?簡單來說,MCP (Model Context Protocol) 是一種讓 AI 變得更聰明的協議,它讓 AI 可以直接使用各種外部工具,例如你的檔案系統、Notion 等等,從而大幅提升 AI 的功能和效率。本文深入淺出地解釋 MCP 的三大組成架構,並透過實際案例和常見問題。
Thumbnail
2025/04/01
什麼是 MCP?簡單來說,MCP (Model Context Protocol) 是一種讓 AI 變得更聰明的協議,它讓 AI 可以直接使用各種外部工具,例如你的檔案系統、Notion 等等,從而大幅提升 AI 的功能和效率。本文深入淺出地解釋 MCP 的三大組成架構,並透過實際案例和常見問題。
Thumbnail
2025/03/30
在現代快節奏的生活中,「今天吃什麼」常常成為一個讓我頭疼的問題。每天面對眾多餐廳選擇,很容易陷入決策疲勞。為了解決這個日常煩惱,我設計了一個簡單的餐廳推薦系統,參考交友軟體的左右滑動機制,讓使用者能夠輕鬆選擇餐廳。 純前端技術(HTML, CSS, JS)搭配GAS
Thumbnail
2025/03/30
在現代快節奏的生活中,「今天吃什麼」常常成為一個讓我頭疼的問題。每天面對眾多餐廳選擇,很容易陷入決策疲勞。為了解決這個日常煩惱,我設計了一個簡單的餐廳推薦系統,參考交友軟體的左右滑動機制,讓使用者能夠輕鬆選擇餐廳。 純前端技術(HTML, CSS, JS)搭配GAS
Thumbnail
2025/03/20
在 Laravel 開發 API 時,直接在 Controller 內進行資料加工可能會讓程式碼變得雜亂且難以維護。因此,Laravel 提供 Resource (資源轉換器) 來解決這個問題,讓我們可以統一管理 API 的輸出格式,將模型model或模型集合collection轉換為適合 API
Thumbnail
2025/03/20
在 Laravel 開發 API 時,直接在 Controller 內進行資料加工可能會讓程式碼變得雜亂且難以維護。因此,Laravel 提供 Resource (資源轉換器) 來解決這個問題,讓我們可以統一管理 API 的輸出格式,將模型model或模型集合collection轉換為適合 API
Thumbnail
看更多
你可能也想看
Thumbnail
介紹朋友新開的蝦皮選物店『10樓2選物店』,並分享方格子與蝦皮合作的分潤計畫,註冊流程簡單,0成本、無綁約,推薦給想增加收入的讀者。
Thumbnail
介紹朋友新開的蝦皮選物店『10樓2選物店』,並分享方格子與蝦皮合作的分潤計畫,註冊流程簡單,0成本、無綁約,推薦給想增加收入的讀者。
Thumbnail
當你邊吃粽子邊看龍舟競賽直播的時候,可能會順道悼念一下2300多年前投江的屈原。但你知道端午節及其活動原先都與屈原毫無關係嗎?這是怎麼回事呢? 本文深入探討端午節設立初衷、粽子、龍舟競渡與屈原自沉四者。看完這篇文章,你就會對端午、粽子、龍舟和屈原的四角關係有新的認識喔。那就讓我們一起解開謎團吧!
Thumbnail
當你邊吃粽子邊看龍舟競賽直播的時候,可能會順道悼念一下2300多年前投江的屈原。但你知道端午節及其活動原先都與屈原毫無關係嗎?這是怎麼回事呢? 本文深入探討端午節設立初衷、粽子、龍舟競渡與屈原自沉四者。看完這篇文章,你就會對端午、粽子、龍舟和屈原的四角關係有新的認識喔。那就讓我們一起解開謎團吧!
Thumbnail
※ 別名: 目的在於提高SQL查詢的可讀性和簡潔性。 ※ 別名有兩種: Column Alias(列別名):在查詢結果中的某一列,取一個臨時的新名字。 Table Alias(表別名):給查詢中的表取一個短暫的新名字。 ※ Column Alias ※ 為什麼需要 Column A
Thumbnail
※ 別名: 目的在於提高SQL查詢的可讀性和簡潔性。 ※ 別名有兩種: Column Alias(列別名):在查詢結果中的某一列,取一個臨時的新名字。 Table Alias(表別名):給查詢中的表取一個短暫的新名字。 ※ Column Alias ※ 為什麼需要 Column A
Thumbnail
※ GROUP BY 用於將數據表中的數據按照一個或多個列進行分組。例如在處理一個表格的資料時,可以指定欄位,一個或是多個,然後把將其視為ID進行分組處理。 ※ 語法 SELECT column1, column2, ..., aggregate_function(column) FROM
Thumbnail
※ GROUP BY 用於將數據表中的數據按照一個或多個列進行分組。例如在處理一個表格的資料時,可以指定欄位,一個或是多個,然後把將其視為ID進行分組處理。 ※ 語法 SELECT column1, column2, ..., aggregate_function(column) FROM
Thumbnail
※ 什麼是WHERE? 使用 WHERE來設定條件,可以幫助我們縮小查詢結果的範圍,取得想要的結果。 ※ 語法: ※ 解析順序: From:先看是哪一張table→table裡面符合Where指定條件的record→再看Select指定的是那些欄位→再根據那個欄位進行排序。 ※ 使⽤⽅
Thumbnail
※ 什麼是WHERE? 使用 WHERE來設定條件,可以幫助我們縮小查詢結果的範圍,取得想要的結果。 ※ 語法: ※ 解析順序: From:先看是哪一張table→table裡面符合Where指定條件的record→再看Select指定的是那些欄位→再根據那個欄位進行排序。 ※ 使⽤⽅
Thumbnail
※ 什麼是ORDER BY? 可以讓SELECT出來的結果,根據你想要的方式排序。簡單說,用於對查詢結果進行排序。 ※ 語法: SELECT select_list FROM table_name ORDER BY column1 [ASC|DESC], column2 [ASC|DESC]
Thumbnail
※ 什麼是ORDER BY? 可以讓SELECT出來的結果,根據你想要的方式排序。簡單說,用於對查詢結果進行排序。 ※ 語法: SELECT select_list FROM table_name ORDER BY column1 [ASC|DESC], column2 [ASC|DESC]
Thumbnail
※ 語法 SELECT select_list FROM table_name​ ※ 解析順序 From:從哪裡拿? SELECT:要 "拿什麼" 資料? ※ 使用場景: Single column(單一欄位): Multiple column(多個欄位): All colu
Thumbnail
※ 語法 SELECT select_list FROM table_name​ ※ 解析順序 From:從哪裡拿? SELECT:要 "拿什麼" 資料? ※ 使用場景: Single column(單一欄位): Multiple column(多個欄位): All colu
Thumbnail
在進行SQL查詢邏輯更改時,需要適當地使用SubQuery和join來達到新的排序需求。本文將介紹原本的撈取邏輯、需求以及如何使用SubQuery來解決新的排序需求。
Thumbnail
在進行SQL查詢邏輯更改時,需要適當地使用SubQuery和join來達到新的排序需求。本文將介紹原本的撈取邏輯、需求以及如何使用SubQuery來解決新的排序需求。
Thumbnail
排序是EXCEL很常用很基礎的一個功能,他可以幫我們把資料依照指定的順序排列。 但通常我們使用都是以欄(直)的方向進行排序,其實EXCEL也可以依據列(橫)的方向進行排續哦😁 下圖是LINE社群網友提出的問題,想要把上圖的原始資料變成下圖。(相關問題可以加入LINE社群唷) 這時候用排序(尋
Thumbnail
排序是EXCEL很常用很基礎的一個功能,他可以幫我們把資料依照指定的順序排列。 但通常我們使用都是以欄(直)的方向進行排序,其實EXCEL也可以依據列(橫)的方向進行排續哦😁 下圖是LINE社群網友提出的問題,想要把上圖的原始資料變成下圖。(相關問題可以加入LINE社群唷) 這時候用排序(尋
Thumbnail
在用 QUERY 查詢資料時,你曾遇過在 WHERE 寫很多個 OR 的狀況嗎?有個更簡單好用的寫法推薦給你,來瞧瞧!
Thumbnail
在用 QUERY 查詢資料時,你曾遇過在 WHERE 寫很多個 OR 的狀況嗎?有個更簡單好用的寫法推薦給你,來瞧瞧!
Thumbnail
這邊統整了所有過去發表過關於 QUERY 函式的教學分享,希望可以方便你按照順序閱讀和練習。 QUERY 可以用來查詢、篩選、聚集、排序資料,還可以做張簡易的資料透視表,是我在 Google 試算表上做數據分析、製作報告、製作儀表板時最常用的函式之一,既方便又好用,誠心推薦!
Thumbnail
這邊統整了所有過去發表過關於 QUERY 函式的教學分享,希望可以方便你按照順序閱讀和練習。 QUERY 可以用來查詢、篩選、聚集、排序資料,還可以做張簡易的資料透視表,是我在 Google 試算表上做數據分析、製作報告、製作儀表板時最常用的函式之一,既方便又好用,誠心推薦!
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News