Truy vấn bản ghi ngẫu nhiên theo nhiều tiêu thức trong SQL Server

Em chào mọi người ạ. Em có một bảng Câu hỏi được thiết kế như trong hình. Mong muốn của em là lấy ra được mảng câu hỏi thoả mãn điều kiện: Vd: Mảng gồm 40 câu hỏi trong đó sẽ lấy ngẫu nhiên nhưng vẫn đảm bảo mỗi chương có ít nhất 1 câu hỏi và với mức độ dễ, tb, khó theo tỷ lệ ( 25, 10, 5). M.n hỗ trợ em với ạ. Em cảm ơn ạ

image

Tớ đưa ra một số giả thiết cho bài toán của cậu để làm đơn giản mọi thứ trước:

  • Cậu có ít hơn 40 chương cho mỗi môn học.
  • Cậu có đủ câu hỏi dễ - vừa - khó trong pool cho từng chương
  • Cậu kỳ vọng các câu hỏi khó - vừa - dễ sẽ dàn đều ra các chương, tức là số lượng chương mà câu hỏi khó - vừa - dễ cover là nhiều nhất có thể.

Sẽ có nhiều cách để làm, cơ mà cậu có thể làm theo chiến lược đơn giản dưới đây xem:

  • Chọn ra 5 câu hỏi khó cho min(5, max(số chương)) chương.
    Cậu có thể random ra các chương sẽ lấy câu hỏi, rồi tìm random câu hỏi trong CSDL.
  • Chọn ra 10 câu hỏi vừa cho min(10, max(số chương còn lại)).
    Nếu cậu đã chọn hết chương rồi mà vẫn còn slot cho câu hỏi vừa, cậu random chọn câu hỏi vừa còn lại.
  • Chọn ra 25 câu hỏi dễ cho min(25, max(số chương còn lại)) chương.
    Nếu cậu đã chọn hết chương rồi mà vẫn còn slot cho câu hỏi vừa, cậu random chọn câu hỏi dễ còn lại.

Đây là cách để cậu chọn random một record ở sql server.

SELECT TOP 1 column FROM table
WHERE <điều kiện lọc của cậu>
ORDER BY NEWID()

Cậu kết hợp các hướng dẫn ở trên và implement thử nhé!

6 Likes

cậu có thể làm demo thử được không?

kiểu với yêu cầu của bạn ấy như thế thì viết câu lênh như nào

Hi there,

Cá nhân tớ thấy chiến lược mô tả ở trên tương đối straight forward. Tuy nhiên, tớ sẽ lấy 1 ví dụ đơn giản để cậu dễ hình dung.

Giả sử cậu có 10 chương. Các bước cậu thực hiện sẽ thế này:

Bước 1:

Cậu sẽ chọn ra 5 chương cho 5 câu hỏi khó.
Có nhiều cách để lấy ngẫu nhiên 5 chương trong 10 chương, cơ mà cách dễ nhất là cậu thực hiện bằng code ở application của cậu. Ví dụ như cậu có các chương [1, 7, 2, 4, 6] được random ra từ ứng dụng.
Cậu có thể convert nó sang symbol table/map/dictionary:

Chương Số lượng câu hỏi
1 1
7 1
2 1
4 1
6 1

Bước 2:

  • Giờ cậu chọn 10 chương để lấy câu hỏi medium.
    Để cho số lượng câu hỏi dàn đều ra các chương, cậu nên ưu tiên lấy ở các chương chưa được chọn ở bước trước, một lần nữa bằng thao tác random trong ứng dụng. Ví dụ, cậu lấy được [3, 5, 10, 8,9].
  • Cậu có thể thấy cậu còn cần 5 chương cho 5 câu hỏi dư ra, giờ cậu có thể random một lần nữa chọn 5 chương mới trong số 10 chương ban đầu.
    Ví dụ, cậu lấy được [10, 5, 2, 7, 6].

Từ 2 list đã có, cậu có các câu hỏi ở các chương [3, 5, 10, 8, 9, 10, 5, 2, 7, 6]
Chuyển thành symbol table:

Chương Số lượng câu hỏi
10 2
1 1
2 1
3 1
5 2
6 1
7 1
8 1
9 1

Bước 3:

Cậu làm y hệt như bước 2.
Giả sử cậu có kết quả chọn 25 chương và chuyển nó thành symbol table như thế này:

Chương Số lượng câu hỏi
10 3
1 2
2 3
3 3
5 2
6 2
7 3
8 2
9 3

Bước 4:

Từ các bảng symbol trên, cậu generate câu SQL để query ra các câu hỏi cậu cần.
Chẳng hạn:

# 1 Câu hỏi dễ chương 1
SELECT TOP 1 * FROM cauhoi
WHERE chuong = 1 AND dokho = 1
ORDER BY NEWID()
UNION ALL
# 1 Câu hỏi dễ chương 7
SELECT TOP 1 * FROM cauhoi
WHERE chuong = 7 AND dokho = 1
ORDER BY NEWID()
# ...

Tớ hi vọng demo nho nhỏ kể trên giúp cậu hiểu được cách làm đơn giản nhất, áp dụng cho bất cứ ngôn ngữ nào.

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?