CHỌN GIỚI HẠN 1 cho mỗi giá trị cột?


10

Hãy nói rằng tôi có bảng sau

-----------------------------
| user_id   | comment       |
-----------------------------
| 2         | thats cool    |
| 2         | awesome       |
| 3         | i hate this   |
| 3         | okay          |
| 6         | this is weird |
| 6         | hello?        |
| 6         | what is it    |
| 9         | how are you   |
| 16        | too slow      |
| 16        | yes           |
| 17        | alrighty      |
-----------------------------

Làm thế nào bạn có thể chọn một hàng mỗi user_id? Vì vậy, kết quả của tôi sẽ là:

-----------------------------
| user_id   | comment       |
-----------------------------
| 2         | thats cool    |
| 3         | i hate this   |
| 6         | this is weird |
| 9         | how are you   |
| 16        | too slow      |
| 17        | alrighty      |
-----------------------------

Điều này có thể với một truy vấn hiệu quả không? Hoặc là lựa chọn phụ cần thiết? Có thể bằng cách nào đó sử dụng DISTINCTtrên một cột duy nhất?

Câu trả lời:


9

Đó là những gì GROUP BYđược sử dụng cho. Nhận một hàng (mỗi nhóm). Trong trường hợp này, nó sẽ hiển thị tất cả các khác biệt user_idgiá trị và cho phần còn lại của các cột, bạn có thể (phải) sử dụng chức năng tổng hợp như MIN(), MAX(), AVG(), SUM()như bạn sẽ có nhiều hơn một giá trị cho mỗi nhóm và chỉ có một có thể được hiển thị.

SELECT
    user_id
  , MIN(comment) AS comment  -- it will show the first in alphabetical order  
                             -- you could also use MAX()
FROM
    tableX
GROUP BY
    user_id ;

MySQL cũng cho phép giải pháp không chính thống sau đây, sẽ trả về một nhận xét (ít nhiều ngẫu nhiên) cho mỗi người dùng:

SELECT
    user_id
  , comment
FROM
    tableX
GROUP BY
    user_id ;

Truy vấn cuối cùng này sẽ không hoạt động nhưng gây ra lỗi nếu ONLY_FULL_GROUP_BYchế độ (nghiêm ngặt hơn) được bật. Trong phiên bản 5.7 được phát hành gần đây, chế độ này là mặc định và một chức năng mới ANY_VALUE(), được cung cấp. Để biết thêm chi tiết, xem phần Xử lý MySQL củaGROUP BY trang. Truy vấn có thể được viết ngay bây giờ:

SELECT
    user_id
  , ANY_VALUE(comment) AS comment
FROM
    tableX
GROUP BY
    user_id ;

Lưu ý rằng với phiên bản "không chính thống" hoặc sử dụng ANY_VALUE()hàm gần đây , nếu chúng tôi thêm nhiều cột trong SELECTdanh sách, các giá trị của chúng không được đảm bảo là từ cùng một hàng, chỉ từ một hàng trong cùng một nhóm. Cách chúng được chọn không chính xác ngẫu nhiên, phụ thuộc vào kế hoạch thực hiện và các chỉ mục được sử dụng.


Có cách nào khác để chỉ định hàng nào được kéo cho user_id không? Bất kỳ cách nào để xác định một thứ tự theo loại?
Jake Wilson

Bên cạnh đó MINMAX?
ypercubeᵀᴹ


2
Bạn cũng sẽ tìm thấy rất nhiều vấn đề tương tự trong trang web SO, dưới [greatest-n-per-group]thẻ.
ypercubeᵀᴹ

1
@ T.BrianJones có nghĩa là bạn trong truy vấn "không chính thống", nếu bạn thêm tất cả các cột khác trong danh sách CHỌN? Đây là lần đầu tiên, họ có thể không đến từ cùng một hàng. Nó không chính xác ngẫu nhiên nhưng các giá trị có thể từ các hàng khác nhau (từ cùng một nhóm).
ypercubeᵀᴹ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.