我想要依照固定排序 Left join最相符的Appoinment
狀況是要列出 各user前/後一筆Appointment,且符合某些條件下必須優先顯示
因為是混合式條件,無法個別判斷後JOIN,故使用ORDER,再用DISTINCT+GROUP
例如: 該user有多筆時 status = 2 優先, status = 1, 再依時間...各種狀態 排序,但只需抓第一筆相符之後,再做Left JOIN
而 DISTINCT+GROUP去抓第一筆的問題在 如何在GROUP後保持排序
用最佳解法做變化,可以有效達成效果
也希望有其他能直接拉出所需資料的方法
==================================================
因為每個Table都很大,所以我另外抓出Filter並排序,到這邊資料出來的狀況和排序都符合預期。
但想要抓出各資料的第一筆時,卻會變回系統排序的第一筆...
基本上order都index過...
希望版上大大可以提供一點建議>"<
主程式為下
SELECT User.*, NextAppointment.*, LastAppointment.*
FROM( User )
LEFT JOIN(
SELECT *, COUNT(DISTINCT( user_id ))
FROM( SELECT Appointment.id, Appointment.user_id
FROM( Appointment )
WHERE Appointment.from_time>='2020-05-26'
AND Appointment.status=1
ORDER BY Appointment.from_time, Appointment.confirmed=1 DESC, Appointment.id DESC
)NextAppointment_sub
GROUP BY user_id
)NextAppointment ON NextAppointment.user_id = User.id
LEFT JOIN(
SELECT *, COUNT(DISTINCT( user_id ))
FROM( SELECT Appointment.id, Appointment.user_id
FROM( Appointment )
WHERE Appointment.from_time<='2020-05-26'
ORDER BY Appointment.status=2 DESC, Appointment.from_time DESC, Appointment.confirmed=1 DESC, Appointment.status=1 DESC, Appointment.id DESC
)LastAppointment_sub
GROUP BY user_id
)LastAppointment ON LastAppointment.user_id = User.id AND LastAppointment.from_time >= User.FirstRequest
在Left join 的子查詢中...
抓取先前的Appointment,並以有狀態優先、時間... 等依序排列後,使用 DISTINCT +GROUP 抓取各user的第一筆符合資料,會變回系統排序
SELECT *, COUNT(DISTINCT( user_id ))
FROM( SELECT Appointment.id, Appointment.user_id
FROM( Appointment )
WHERE Appointment.from_time<='2020-05-26'
ORDER BY Appointment.status=2 DESC, Appointment.from_time DESC, Appointment.confirmed=1 DESC, Appointment.status=1 DESC, Appointment.id DESC
)LastAppointment_sub
GROUP BY user_id
目前看不太出來你的問題點是什麼。
主要是你「但想要抓出各資料的第一筆時」這句話。
我不太明白你的問題重點。
可否在細說一下嘛?
因為就目前而言,看你的程式碼就是一個user對應2個left join過的東西。
你說的所謂各資料的第一筆指的是哪一個第一筆。這是我目前不懂的地方。
Left Join 的子查詢結果的,每user的第一筆
這樣我了解你的問題了。
其實我還在納悶你為何要用 DISTINCT
使用 DISTINCT 後會讓你原本排序好的資料再重新排序。
所以,你只能往不用 DISTINCT 的方式來達到你要的數據
基本上目前我不太明白
「COUNT(DISTINCT( user_id ))」
你打算拿他來做什麼。但理論上這樣子用。出來的結果理論上因該也是1吧?這基本上是給沒用子查尋時用的方法。
你都已經用了子查尋排序好了。也沒必要再用 DISTINCT 來破壞掉你排好的資料才對了。
會做這處理是因為Appointment表實在太大,且其實只需要排序下的第一筆相符資料,所以打算在Left join之前先做判斷+GROUP user處裡
確實這得要想一下。
我以前的做法是再多一次子查尋。
現在新的做法則是在架構上改變,不要再出現這樣的寫法。
畢竟資料大真的很傷腦筋。
其實如果你的table有說清楚及可能性的資料,還有對應的索引。
搞不好可以用另外的方式來處理。
但目前對你的資料情況不是很了解。所以也沒辦法很有效給你建議就是了。
主要狀況是要列出 各user前/後一筆Appointment,且符合某些條件下必須優先顯示
因為是混合式條件,無法個別判斷後JOIN,故使用ORDER
例如: 該user有多筆時 status = 2 優先, status = 1, 再依時間...各種狀態 排序
而 DISTINCT+GROUP去抓第一筆的問題在 如何在GROUP後保持排序
用最佳解法做變化可以有效達成此效果
我很佩服大家寫SQL的功力,每次都能寫出讓我看半天都不一定看的懂的一長串SQL語法
我看了一下樓主寫的需求,其實也不難呀,我的作法會是:
1.先DISTINCT user_id並排序
2.再用cursor針對每個user_id作from_time,status,confirmed的判斷及排序,取每個user_id的Top 1