Chào mọi người, lại là mình đây, ở phần trước mình đã giới thiệu với mọi người về Show I. ROW_NUMBER()Tên hàm đã nói lên tất cả, đánh số thứ tự các bản ghi
theo thứ tự order với từng partition. Ví dụ: đánh số thứ tự học sinh theo từng lớp chẳng hạn, hãy cố thử nghĩ cách làm nếu không sử dụng
Bạn thấy không, II. RANK()Xếp rank, vâng. Thật sự là trong quá trình làm việc, mình rất hay
Đơn giản đúng không, nhưng query như này thì
Quá nhanh, quá nguy hiểm đúng không? =))) Nhưng cùng một lớp xếp rank vơi nhau làm *éo gì. Xếp rank theo lớp đi... OK, có ngay
Tén ten, có vẻ ngon rồi
đúng không, nhưng bạn có để ý kĩ là trường hợp nếu rank bằng nhau thì sẽ bị miss các rank sau không? ví dụ vs III. dense_rank()Ở bài trước chúng ta đã nói qua cộng
với một chút
Ngon chưa!. IV. LAG() và LEAD()2 hàm này khá hữu ích cho việc tracking sự phát triển, doanh thu của một công ty theo tháng, hay tiến độ học tập của học sinh qua từng năm theo từng môn học. bằng cách so sánh row hiện tại với các row trước - LAG() hay các row sau - LEAD(). Cú pháp đầy đủ:
Hàm trả về giá trị của n hàng trước kể từ row hiện tại, nếu không tồn tại hàng đó thì trả về giá trị default. Trường hợp để trống N & default thì mặc định N = 1 và default = NULL.
Tương tự như hàm
LAG nhưng là trả về giá trị của hàng sau tính từ row hiện tại. Cùng test về độ
Từ bảng trên, dựa vào V FIRST_VALUE() & LAST_VALUE() & NTH_VALUE()Nhìn chung thì 3 hàm này cũng same same 2 hàm trên, cũng để trả về giá trị của 1 hàng, khác nhau là vị trí của hàng đó thối.
Cú pháp đơn giản:
Các hàm còn lại mình thấy khá ít dùng, nếu mọi người muốn tìm hiểu thì có thể đọc doc ở đây nha. Bài toán x10 lươngNói đùa mọi người vậy thôi, tuy không đc x10 lương nhưng bạn sẽ được đánh giá cao nếu giải quyết đc bài toán này (Cá nhân mình nghĩ vậy - có thể vẫn dễ đối với mọi người thì mn đừng cười mình nha) Bài toán này chính xác là xảy ra đối với dự án mình: (mình sẽ biến tấu bài toán đi nhưng vẫn giữ được ý chính nhằm đảm bảo tính bảo mật dự án nha) Tóm tắt: 1 bảng ví của users có khoảng hơn 60tr bản ghi. mỗi user có rất nhiều account (có thể lên đến mấy trăm nghìn bản ghi 1 user) với số tiền khác nhau, các account có sự ưu tiên, tức là phải tiêu hết account này mới được sử dụng đến account khác. Mỗi 1 lần giao dịch bạn phải trừ tiền lần lượt ở các account (đã đảm bảo check đủ tiền). Và 1 giờ 1 user giao dịch rất rất nhiều lần. Hãy giải quyết, tối ưu query để giải bài toán trên. *Ví dụ data cho mọi người hình dung:
Hãy suy nghĩ thử xem trước khi kéo xuống xem gợi ý nha. Solution: Thoạt nhìn thì thấy có vẻ đơn gián đúng không? cứ query lấy ra hết các ví tiền của user theo thứ tự ra rồi For trừ tiền dần thôi, bao giờ đủ thì break. Nhìn có vẻ ok, nhưng nên nhớ, table có đến 60tr bản ghi, mỗi user có thể lên đên hơn 100k bản ghi. chẳng hạn giao dịch chỉ cần đến 1 bản ghi thì cũng lôi hết bản ghi ra thì khác nào vác Dao mổ trâu để chặt gà à. Không ổn rồi: Cần lấy ra đủ bản ghi để xử lý thôi!! Cách 1: Cách này mình làm trước khi biết đến
kết quả: Cách 2: Sử dụng
Kết quả:
Bài toán số 2: (ngoài lề) Bài này mình đang làm trong dự án luôn. Tóm tắt qua thì, khi chơi bài Baracat (đặt cược) 1 user có thể thắng-thua-hòa (có 3 cửa: Player-Banker-Tie, luật thì mọi người có thể tìm hiểu trên GG nha), bây giờ Khách Hàng muốn tạo event dạng: trao thưởng cho TOP những người chơi thắng liên tiếp cao nhất, TOP những người chơi thua liên tiếp nhỏ nhất... (Còn nhiều chỉ tiêu để 1 user đc xếp rank lắm, nào là chơi tối thiếu bao nhiêu ván, phải cược vào cửa nào... Nếu nói hết tiêu chí ra để xếp rank thì chắc choáng luôn). Để tiện dễ hình dung thì mình sẽ convert sang 1 dạng bài mà chúng ta vẫn hay làm giải thuật. Tìm dãy số dương liên tiếp dài nhất (0 thì skip), nhưng thay vì là array thì đây lại là database, và không phải là 1 dãy, mà là rất nhiều dãy tương ứng với nhiếu users. Nhưng, cứ phát triển từ base trc đã Lại là data mẫu cho mọi người dễ tưởng tượng (cho 1 user)Đáp án là 4, mọi người thử làm xem có ra k nhé =)) Nếu có gì thắc mắc thì comment nha. mình cùng nhau trao đổi. Lời giải chi tiết mình sẽ upload sau nha (Hoặc mọi người có thể ping mình )Cám ơn mọi người đã theo dõi bài viết của mình! Chúc mọi người một ngày làm việc vui vẻ!. Tài liệu liên quanhttps://dev.mysql.com/doc/refman/8.0/en/window-function-descriptions.html. https://dev.mysql.com/doc/refman/8.0/en/window-functions-usage.html. https://dev.mysql.com/doc/refman/8.0/en/window-functions-frames.html. |