2008-12-29 26 views
7

Làm cách nào để kết hợp How to request a random row in SQL?Multiple random values in SQL Server 2005 để chọn N hàng ngẫu nhiên bằng một truy vấn SQL thuần túy? Lý tưởng nhất, tôi muốn tránh việc sử dụng các thủ tục được lưu trữ nếu có thể. Điều này thậm chí có thể?Làm cách nào để chọn N hàng ngẫu nhiên bằng SQL thuần túy?

GIẢI:

  1. SQL tinh khiết dùng để càng gần càng tốt với tiêu chuẩn ANSI/ISO.
  2. Giải pháp phải "đủ hiệu quả". Cấp ORDER BY RAND() có thể làm việc nhưng như những người khác đã chỉ ra điều này là không khả thi cho các bảng có kích thước trung bình.

Trả lời

2

Tôi không biết về tinh khiết ANSI, và nó không phải là đơn giản, nhưng bạn có thể kiểm tra câu trả lời của tôi đến một câu hỏi tương tự ở đây: Simple Random Samples from a Sql database

+0

Nó không rõ ràng với tôi làm thế nào để thực hiện những gì bạn đề xuất nếu giả định # 3 là sai (có nghĩa là, bảng của bạn có lỗ). – Gili

+0

Bạn phải viết lại toàn bộ bảng để giả định # 3 là đúng, vì vậy nó là một hoạt động O (n) rất chậm. Tạo một bảng mới với các cột giống như bảng gốc, và cũng là cột nhận dạng cho khóa chính mới sẽ không có khoảng trống. Sau đó chèn toàn bộ bảng gốc vào bảng mới. – user12861

4

Câu trả lời cho câu hỏi của bạn là trong liên kết thứ hai có:

SELECT * FROM table ORDER BY RAND() LIMIT 1 

Chỉ cần thay đổi giới hạn, và/hoặc viết lại cho SQL Server:

SELECT TOP 1 * FROM table ORDER BY newid() 

Bây giờ, này Nghiêm trả lời câu hỏi của bạn, nhưng bạn thực sự không nên sử dụng giải pháp này. Chỉ cần thử nó trên một cái bàn lớn và bạn sẽ thấy những gì tôi có ý nghĩa.

Nếu không gian khóa của bạn là tuần tự, không có lỗ, hoặc có rất ít lỗ và nếu có rất ít lỗ, bạn không quá lo ngại rằng một số hàng có cơ hội được chọn cao hơn một chút sau đó bạn có thể sử dụng biến thể mà bạn tính toán khóa nào bạn muốn truy xuất ngẫu nhiên, từ 1 đến khóa cao nhất trong bảng của bạn và sau đó truy lục hàng đầu tiên có khóa bằng hoặc cao hơn số bạn đã tính. Bạn chỉ cần phần "cao hơn" nếu khóa-không gian của bạn có lỗ.

SQL này được để lại như một bài tập cho người đọc.


Sửa: Lưu ý, một bình luận cho câu trả lời khác ở đây đề cập đến rằng có lẽ SQL tinh khiết nghĩa ANSI SQL tiêu chuẩn. Nếu đó là trường hợp, thì không có cách nào, vì không có hàm ngẫu nhiên chuẩn hóa, cũng như mọi công cụ cơ sở dữ liệu đều xử lý hàm số ngẫu nhiên theo cùng một cách. Ít nhất một công cụ tôi đã thấy "tối ưu hóa" cuộc gọi bằng cách gọi nó một lần và chỉ lặp lại giá trị được tính cho tất cả các hàng.

+0

NEWID() là một ý tưởng tồi nếu bạn muốn các mẫu thật sự ngẫu nhiên, GUID có nhiều cấu trúc. Nếu bạn không quan tâm đến việc thực sự là ngẫu nhiên, hãy tiếp tục. – user12861

1

Dưới đây là một giải pháp tiềm năng, mà sẽ cho phép bạn cân bằng rủi ro nhận được ít hơn N hàng chống lại một thiên vị lấy mẫu từ "phía trước" của bảng. Điều này giả định rằng N nhỏ so với kích thước của bảng:

select * from table where random() < (N/(select count(1) from table)) limit N; 

Điều này thường sẽ lấy mẫu hầu hết bảng, nhưng có thể trả về ít hơn N hàng. Nếu có một số sai lệch là chấp nhận được, tử số có thể được thay đổi từ N thành 1.5 * N hoặc 2 * N để làm cho nó rất có khả năng N hàng sẽ được trả về. Ngoài ra, nếu nó là cần thiết để ngẫu nhiên thứ tự hàng, không chỉ chọn một tập hợp con ngẫu nhiên:

select * from (select * from table 
       where random() < (N/(select count(1) from table)) limit N) 
order by mod(tableid,1111); 

Nhược điểm của giải pháp này là, ít nhất là trong PostgreSQL, nó sử dụng một máy quét tuần tự của bảng.Một tử số lớn hơn sẽ tăng tốc truy vấn.

-1

Đó có thể giúp bạn:

SELECT TOP 3 * FROM TABLE ORDER BY NEWID() 
+0

-1, đã được bao gồm bởi http://stackoverflow.com/a/396946/14731 và không phải là SQL thuần túy (newid() là Microsoft cụ thể). – Gili

-2

Sử dụng mã dưới đây bạn có thể đạt được như vậy bạn đang tìm kiếm ..

select top 1 * from student1 order by newid() 

giá trị thay đổi của N trong đó top 1, do đó bạn sẽ nhận được con số đó các bản ghi ngẫu nhiên.

+0

-1, đã được che phủ bởi stackoverflow.com/a/396946/14731 và không phải là SQL thuần túy (newid() là Microsoft cụ thể). – Gili

Các vấn đề liên quan