Back-tick là một thứ MySQL không chuẩn. Sử dụng dấu ngoặc kép chính tắc để trích dẫn số nhận dạng (cũng có thể trong MySQL). Đó là, nếu bảng của bạn trên thực tế được đặt tên là "MY_TABLE"
(tất cả các chữ hoa). Nếu bạn (khôn ngoan hơn) đặt tên cho nó là my_table
(tất cả chữ thường), sau đó bạn có thể xóa dấu ngoặc kép hoặc sử dụng chữ thường.
Ngoài ra, tôi sử dụng ct
thay vì count
dưới dạng bí danh, vì việc sử dụng tên hàm làm số nhận dạng là không tốt.
Trường hợp đơn giản
Điều này sẽ hoạt động với PostgreSQL 9.1 :
SELECT *, count(id) ct
FROM my_table
GROUP BY primary_key_column(s)
ORDER BY ct DESC;
Nó yêu cầu (các) cột khóa chính trong GROUP BY
mệnh đề. Kết quả giống hệt nhau đến một truy vấn MySQL, nhưng ct
sẽ luôn là 1 (hoặc 0 nếu id IS NULL
) - vô ích khi tìm các bản sao.
Nhóm theo các cột ngoài khóa chính
Nếu bạn muốn nhóm theo (các) cột khác, mọi thứ sẽ phức tạp hơn. Truy vấn này bắt chước hành vi của truy vấn MySQL của bạn - và bạn có thể sử dụng *
.
SELECT DISTINCT ON (1, some_column)
count(*) OVER (PARTITION BY some_column) AS ct
,*
FROM my_table
ORDER BY 1 DESC, some_column, id, col1;
Điều này hoạt động vì DISTINCT ON
(PostgreSQL cụ thể), như DISTINCT
(SQL-Standard), được áp dụng sau hàm cửa sổ count(*) OVER (...)
. Chức năng cửa sổ
(với OVER
mệnh đề) yêu cầu PostgreSQL 8.4 trở lên và không khả dụng trong MySQL.
Hoạt động với bất kỳ bảng nào, bất kể ràng buộc chính hay duy nhất.
1
trong DISTINCT ON
và ORDER BY
chỉ là cách viết tắt để chỉ số thứ tự của mục trong SELECT
danh sách.
SQL Fiddle để chứng minh cả hai bên cạnh nhau.
Thêm chi tiết trong câu trả lời có liên quan chặt chẽ này:
count(*)
so với count(id)
Nếu bạn đang tìm kiếm các bản sao, tốt hơn hết bạn nên sử dụng count(*)
hơn với count(id)
. Có một sự khác biệt nhỏ nếu id
có thể là NULL
, bởi vì NULL
giá trị không được tính - trong khi count(*)
đếm tất cả các hàng. Nếu id
được định nghĩa NOT NULL
, kết quả giống nhau, nhưng count(*)
nói chung là thích hợp hơn (và cũng nhanh hơn một chút).