2013-06-04 36 views
64

Tôi có một bảng trên pgsql với tên (có nhiều hơn 1 mio. Hàng), nhưng tôi cũng có nhiều bản sao. Tôi chọn 3 trường: id, name, metadata.Postgres: Khác biệt nhưng chỉ cho một cột

Tôi muốn chọn ngẫu nhiên chúng với ORDER BY RANDOM()LIMIT 1000, vì vậy tôi thực hiện việc này là nhiều bước để lưu một số bộ nhớ trong tập lệnh PHP của tôi.

Nhưng làm cách nào tôi có thể làm điều đó để nó chỉ cung cấp cho tôi danh sách không có trùng lặp trong tên.

Ví dụ: [1,"Michael Fox","2003-03-03,34,M,4545"] sẽ được trả lại nhưng không được trả lại [2,"Michael Fox","1989-02-23,M,5633"]. Trường tên là quan trọng nhất và phải là duy nhất trong danh sách mỗi khi tôi thực hiện lựa chọn và nó phải là ngẫu nhiên.

Tôi đã thử với GROUP BY name, sau đó tôi hy vọng tôi có id và siêu dữ liệu trong GROUP BY cũng như trong chức năng tăng cường, nhưng tôi không muốn có chúng bằng cách nào đó được lọc.

Bất kỳ ai biết cách tìm nạp nhiều cột nhưng chỉ phân biệt trên một cột?

Trả lời

135

Để làm một khác biệt trên chỉ có một (hoặc n) cột (s):

select distinct on (name) 
    name, col1, col2 
from names 

này sẽ trả lại bất kỳ của các hàng có chứa tên. Nếu bạn muốn kiểm soát những hàng nào sẽ được trả lại, bạn cần phải đặt hàng:

select distinct on (name) 
    name, col1, col2 
from names 
order by name, col1 

Sẽ trả về hàng đầu tiên khi có lệnh col1.

distinct on:

SELECT DISTINCT ON (expression [, ...]) giữ chỉ hàng đầu tiên của mỗi bộ hàng nơi các biểu thức được đánh giá để bình đẳng. Các biểu thức DISTINCT ON được diễn giải bằng cách sử dụng các quy tắc tương tự như đối với ORDER BY (xem ở trên). Lưu ý rằng “hàng đầu tiên” của mỗi bộ là không thể đoán trước trừ khi ORDER BY được sử dụng để đảm bảo rằng hàng mong muốn xuất hiện đầu tiên.

(các) biểu thức TRÊN phải khớp với đơn đặt hàng bên trái bên trái (các) biểu thức. Mệnh đề ORDER BY thường chứa các biểu thức bổ sung xác định mức ưu tiên mong muốn của các hàng trong mỗi nhóm DISTINCT ON.

+0

Bắt tốt khi đặt hàng. Tôi đã không bao gồm nó bởi vì họ đã đề cập muốn có một thứ tự ngẫu nhiên, nhưng điều quan trọng là phải đề cập đến. –

+0

có, thứ tự cũng quan trọng, cảm ơn. – NovumCoder

+0

Yêu cầu 'đặt hàng theo tên' phải không? Nó sẽ tạo ra một kết quả khác với 'thứ tự bởi col1'? –

2
SELECT NAME,MAX(ID) as ID,MAX(METADATA) as METADATA 
from SOMETABLE 
GROUP BY NAME 
+2

Chỉ cần cảnh báo: có thể không trả lại giá trị ID hoặc giá trị siêu dữ liệu thuộc về "cùng nhau" –

+0

Hm do đó điều này có nghĩa là sql không chính xác? – NovumCoder

+0

@Novum No. Điều đó có nghĩa là mèo lấy một giá trị id từ một trong các hàng của Michael và siêu dữ liệu từ một hàng khác vì nó được yêu cầu cho số lần tối đa của Michael. –

12

Bất kỳ ai biết cách tìm nạp nhiều cột nhưng chỉ phân biệt trên một cột?

Bạn muốn the DISTINCT ON clause.

Bạn không cung cấp dữ liệu mẫu hoặc truy vấn hoàn chỉnh để tôi không có gì để hiển thị cho bạn. Bạn muốn viết một cái gì đó như:

SELECT DISTINCT ON (name) fields, id, name, metadata FROM the_table; 

Điều này sẽ trả về một nhóm hàng không thể đoán trước (nhưng không phải ngẫu nhiên). Nếu bạn muốn làm cho nó có thể dự đoán, hãy thêm một số ORDER BY cho mỗi câu trả lời của Clodaldo. Nếu bạn muốn làm cho nó thật sự ngẫu nhiên, bạn sẽ muốn ORDER BY random().