Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

hiển thị nhận xét cuối cùng mà chỉ 1 nhận xét cho mỗi người dùng

Tại sao nó không hoạt động với GROUP BY

SELECT * không thể được sử dụng với GROUP BY; nó là SQL không hợp lệ. GROUP BY không chọn các hàng trong bảng. Nó tạo các nhóm hàng bằng cách sử dụng các biểu thức được cung cấp, sau đó từ mỗi nhóm, nó tạo một bản ghi mới và tính toán từng cột của bản ghi mới này bằng cách sử dụng các giá trị có trong biểu thức.

Các cột xuất hiện trong SELECT mệnh đề phải đáp ứng một trong các quy tắc sau:

  • cũng xuất hiện trong GROUP BY mệnh đề;
  • được sử dụng với GROUP BY tổng hợp các chức năng ;
  • phụ thuộc vào chức năng của các cột xuất hiện trong GROUP BY mệnh đề.

Trong khi * là một lối tắt cho tất cả các tên cột của (các) bảng được truy vấn sử dụng, chỉ dành cho truy vấn của bạn user cột đáp ứng một trong các yêu cầu trên.

Trước phiên bản 5.7.5 MySQL không triển khai quy tắc thứ ba ở trên. Nó được sử dụng để chấp nhận các truy vấn có trong SELECT các cột mệnh đề không theo sau bất kỳ cột nào trong GROUP BY các yêu cầu. Giá trị được trả về bởi truy vấn cho các cột như vậy là không xác định .

Kể từ phiên bản 5.7.5, MySQL từ chối GROUP BY các truy vấn đáp ứng các yêu cầu.

Giải pháp

Dù bằng cách nào, giải pháp cho vấn đề của bạn không liên quan đến GROUP BY . Nó có thể được thực hiện dễ dàng bằng cách sử dụng LEFT JOIN với các điều kiện chính xác:

SELECT lc.*
FROM comments lc               # 'lc' from 'last comment'
    LEFT JOIN comments nc      # 'nc' from 'newer comment'
        ON lc.user = nc.user   # both comments belong to the same user
        AND lc.id < nc.id      # 'nc' is newer than 'lc'
WHERE nc.id IS NULL            # there is no 'newer comment'
ORDER BY lc.id DESC
LIMIT 10

Cách hoạt động

Nó tham gia vào bảng comments , bí danh là lc ("lc" từ "nhận xét cuối cùng" của người dùng) so với chính nó, bí danh là nc ("nc" từ "bình luận mới hơn"). Mệnh đề kết hợp khớp với từng mục nhập của lc với tất cả các mục nhập của nc thuộc về cùng một người dùng (lc.user = nc.user ) và mới hơn (lc.id < nc.id; Tôi giả định rằng các ID được chỉ định tuần tự và các nhận xét mới hơn có giá trị lớn hơn cho id ).

Việc sử dụng LEFT JOIN đảm bảo rằng mọi hàng của lc xuất hiện trong kết quả của phép nối, ngay cả khi không tìm thấy hàng phù hợp nào trong nc (vì không có bình luận mới hơn của cùng một người dùng). Trong trường hợp này, NULL được sử dụng thay cho các trường của nc . WHERE mệnh đề giữ trong kết quả cuối cùng chỉ đặt các hàng có NULL trong nc.id; điều này có nghĩa là trong lc phần chúng chứa nhận xét gần đây nhất của mỗi người dùng.

SELECT mệnh đề chứa tất cả các trường của lc (của nc đều là NULL , dù sao). ORDER BY mệnh đề có thể được sử dụng để sắp xếp tập kết quả. ORDER BY lc.id DESC đặt các nhận xét gần đây nhất lên đầu tiên và LIMIT mệnh đề giữ kết quả được đặt ở kích thước phù hợp.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Thiết lập truy vấn cho trường cụ thể của thực thể Hibernate

  2. Tối ưu hóa việc lặp qua mảng bằng cách sử dụng vòng lặp foreach

  3. MySQL:trả về tối đa 5 chữ số cuối cùng từ cột

  4. Sắp xếp ngẫu nhiên ổn định / có thể lặp lại (MySQL, Rails)

  5. Tự động chèn giá trị vào bảng từ phạm vi