[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
欸! 是彼得的資料庫
85會員
58內容數
歡迎來到彼得的沙龍,在這裡,我將與你分享書籍精華的智慧、人際溝通的技巧、理財增值的秘訣,以及情緒管理的策略。不僅幫助你打好財務基礎,還能引領你在人生的每個環節中游刃有餘。如果你渴望成長,並追求更充實的生活,這裡就是你值得關注的空間。立即加入,與我一起探索成長的無限可能!
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
※ 語法 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
※ GROUP BY 用於將數據表中的數據按照一個或多個列進行分組。例如在處理一個表格的資料時,可以指定欄位,一個或是多個,然後把將其視為ID進行分組處理。 ※ 語法 SELECT column1, column2, ..., aggregate_function(column) FROM
Thumbnail
※ GROUP BY 用於將數據表中的數據按照一個或多個列進行分組。例如在處理一個表格的資料時,可以指定欄位,一個或是多個,然後把將其視為ID進行分組處理。 ※ 語法 SELECT column1, column2, ..., aggregate_function(column) FROM
Thumbnail
在進行SQL查詢邏輯更改時,需要適當地使用SubQuery和join來達到新的排序需求。本文將介紹原本的撈取邏輯、需求以及如何使用SubQuery來解決新的排序需求。
Thumbnail
在進行SQL查詢邏輯更改時,需要適當地使用SubQuery和join來達到新的排序需求。本文將介紹原本的撈取邏輯、需求以及如何使用SubQuery來解決新的排序需求。
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
排序是EXCEL很常用很基礎的一個功能,他可以幫我們把資料依照指定的順序排列。 但通常我們使用都是以欄(直)的方向進行排序,其實EXCEL也可以依據列(橫)的方向進行排續哦😁 下圖是LINE社群網友提出的問題,想要把上圖的原始資料變成下圖。(相關問題可以加入LINE社群唷) 這時候用排序(尋
Thumbnail
排序是EXCEL很常用很基礎的一個功能,他可以幫我們把資料依照指定的順序排列。 但通常我們使用都是以欄(直)的方向進行排序,其實EXCEL也可以依據列(橫)的方向進行排續哦😁 下圖是LINE社群網友提出的問題,想要把上圖的原始資料變成下圖。(相關問題可以加入LINE社群唷) 這時候用排序(尋
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
本文分析導演巴里・柯斯基(Barrie Kosky)如何運用極簡的舞臺配置,將布萊希特(Bertolt Brecht)的「疏離效果」轉化為視覺奇觀與黑色幽默,探討《三便士歌劇》在當代劇場中的新詮釋,並藉由舞臺、燈光、服裝、音樂等多方面,分析該作如何在保留批判核心的同時,觸及觀眾的觀看位置與人性幽微。
Thumbnail
※ 別名: 目的在於提高SQL查詢的可讀性和簡潔性。 ※ 別名有兩種: Column Alias(列別名):在查詢結果中的某一列,取一個臨時的新名字。 Table Alias(表別名):給查詢中的表取一個短暫的新名字。 ※ Column Alias ※ 為什麼需要 Column A
Thumbnail
※ 別名: 目的在於提高SQL查詢的可讀性和簡潔性。 ※ 別名有兩種: Column Alias(列別名):在查詢結果中的某一列,取一個臨時的新名字。 Table Alias(表別名):給查詢中的表取一個短暫的新名字。 ※ Column Alias ※ 為什麼需要 Column A
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
背景:從冷門配角到市場主線,算力與電力被重新定價   小P從2008進入股市,每一個時期的投資亮點都不同,記得2009蘋果手機剛上市,當時蘋果只要在媒體上提到哪一間供應鏈,隔天股價就有驚人的表現,當時光學鏡頭非常熱門,因為手機第一次搭上鏡頭可以拍照,也造就傳統相機廠的殞落,如今手機已經全面普及,題
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
《轉轉生》(Re:INCARNATION)為奈及利亞編舞家庫德斯.奧尼奎庫與 Q 舞團創作的當代舞蹈作品,結合拉各斯街頭節奏、Afrobeat/Afrobeats、以及約魯巴宇宙觀的非線性時間,建構出關於輪迴的「誕生—死亡—重生」儀式結構。本文將從約魯巴哲學概念出發,解析其去殖民的身體政治。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
這是一場修復文化與重建精神的儀式,觀眾不需要完全看懂《遊林驚夢:巧遇Hagay》,但你能感受心與土地團聚的渴望,也不急著在此處釐清或定義什麼,但你的在場感受,就是一條線索,關於如何找著自己的路徑、自己的聲音。
Thumbnail
※ 什麼是WHERE? 使用 WHERE來設定條件,可以幫助我們縮小查詢結果的範圍,取得想要的結果。 ※ 語法: ※ 解析順序: From:先看是哪一張table→table裡面符合Where指定條件的record→再看Select指定的是那些欄位→再根據那個欄位進行排序。 ※ 使⽤⽅
Thumbnail
※ 什麼是WHERE? 使用 WHERE來設定條件,可以幫助我們縮小查詢結果的範圍,取得想要的結果。 ※ 語法: ※ 解析順序: From:先看是哪一張table→table裡面符合Where指定條件的record→再看Select指定的是那些欄位→再根據那個欄位進行排序。 ※ 使⽤⽅
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News