Mysql
使用 group by 過濾子查詢結果
我有一個有效的連接,但看起來很笨拙,因為它對子查詢進行排序並使用 group by 過濾除頂部子查詢結果之外的所有內容。如果不這樣做,將返回 s 和 print_issues.pub_date 的笛卡爾積。
SELECT print_issues.pub_date, print_issues.x, s.page_size FROM print_issues, ( select pub_date, page_size from print_page_size, print_issues where effective_date < print_issues.pub_date order by effective_date desc ) as s WHERE s.pub_date = print_issues.pub_date group by print_issues.pub_date order by print_issues.pub_date desc
該查詢是
print_page_size
. 該表具有列page_size
和effective-date
。以更大的新條目effective_date
取代舊條目。查詢的目標是在每個問題發佈時將print_issue
表與有效的表結合起來。page_size
Sample Data: TABLE: print_page_size ====================== effective_date page_size 2014-01-01 100 2017-05-01 105 TABLE: print_issues =================== pub_date x 2017-04-26 "Random" 2017-05-02 "Data" OUTPUT ====== print_issues.pub_date print_issues.x s.page_size 2017-04-26 "Random" 100 2017-05-02 "Data" 105
我的問題:這種方法有問題嗎?有沒有更直接的方法來達到預期的結果?
您的查詢是非確定性的,因為它濫用
GROUP BY
.它可能會在任何版本的 MySQL 中給出不正確/意外的結果,具體取決於執行計劃和可用索引。您可能沒有看到這樣的行為,因為它還沒有發生(您很幸運,或者表的索引和大小到目前為止已經導致了能夠給出正確結果的計劃)或者它發生了但您沒有註意到。
在某些版本(MariaDB 5.3+)中,類似的查詢——不確定這個但類似——幾乎總是會給出不正確的結果,因為一些優化會刪除
ORDER BY
子查詢中的冗餘。如果您嘗試查詢,則在某些版本的 MySQL (5.7) 中會出現錯誤 - 正是因為它可能會給出不一致的結果。在該版本中,您必須更改預設設置(並獲得錯誤的非確定性行為),否則您必須重寫/更正查詢。
簡而言之,不要使用它。
我會這樣寫查詢。更簡單,確定性並且可能更有效,因為沒有
GROUP BY
並且不會pi
兩次加入表:SELECT pi.pub_date, pi.x, ( SELECT pps.page_size FROM print_page_size AS pps WHERE pps.effective_date < pi.pub_date ORDER BY pps.effective_date DESC LIMIT 1 ) AS page_size FROM print_issues AS pi ORDER BY pub_date ; -- or whatever
上的索引
print_page_size (effective_date, pagesize)
將是進一步的幫助。