Tôi có một hệ thống theo dõi xem tài liệu nào người dùng xem. Mỗi tài liệu có ID của nó và một cụm mà nó thuộc về. Hệ thống của tôi theo dõi ID phiên và số lượt xem. Bây giờ tôi muốn xây dựng một truy vấn SQL sẽ cung cấp cho tôi hai cột - ID phiên và cụm được phân loại. Thuật toán phân loại rất đơn giản:Phân loại SQL
1. select all sessions
2. for each session S
I. prepare an accumulator ACC for clusters
II. select the clusters of viewed documents for this session
III. for each cluster C accumulate the cluster count (ACC[C]++)
IV. find the maximum in the ACC. That is the cluster that the session was classified to
Bảng cấu trúc như sau, tôi đang sử dụng MySQL 5.5.16:
phiên
+-------+-----------+--------------------+
| ID | sessionID | classified_cluster |
+-------+-----------+--------------------+
SessionDocument
+-------+-----------+------------+
| ID | sessionID | documentID |
+-------+-----------+------------+
Cụm
+-------+-------+
| ID | label |
+-------+-------+
ClusterDocument
+-------+-----------+------------+
| ID | clusterID | documentID |
+-------+-----------+------------+
Vì vậy, về cơ bản, tôi muốn chọn các cụm cho mỗi phiên, đếm sự xuất hiện của mỗi cụm cho các tài liệu đã xem và thấy sự xuất hiện tối đa. Sau đó, ID của cụm đã xảy ra nhiều nhất, là kết quả cho phiên làm việc do đó tập kết quả cuối cùng giữ session ID và xảy ra cụm nhất:
quả
+-----------+-----------------------+
| sessionID | classifiedIntoCluster |
+-----------+-----------------------+
tôi quản lý để có được những cụm các tài liệu đã xem cho mỗi phiên (bước 2/II.) với truy vấn này:
SELECT SD.session_id, CD.cluster_id
FROM cluster_document AS CD
INNER JOIN session_document AS SD
ON CD.document_id = SD.document_id
WHERE session_id IN (SELECT session_id FROM session)
Tôi đang gặp khó khăn trong việc tìm phần còn lại. Điều này thậm chí có thể với các truy vấn SELECT lồng nhau không? Tôi có nên sử dụng con trỏ hay không và nếu có, ai đó có thể hiển thị ví dụ bằng con trỏ không? Bất kỳ trợ giúp sẽ được nhiều đánh giá cao.
EDIT # 1: thêm một C# thực hiện, MySQL đổ và kết quả dự kiến
C# thực hiện
private void ClassifyUsers() {
int nClusters = Database.SelectClusterCount(); //get number of clusters
DataSet sessions = Database.SelectSessions(); //get all sessions
foreach (DataRow session in sessions.Tables[0].Rows) { //foreach session
int[] acc = new int[nClusters]; //prepare an accumulator for each known cluster
string s_id = session["session_id"].ToString();
DataSet sessionClusters = Database.SelectSessionClusters(s_id); //get clusters for this session
foreach (DataRow cluster in sessionClusters.Tables[0].Rows) { //for each cluster
int c = Convert.ToInt32(cluster["cluster_id"].ToString()) - 1;
acc[c]++; //accumulate the cluster count
}
//find the maximum in the accumulator -> that is the most relevant cluster
int max = 0;
for (int j = 0; j < acc.Length; j++) {
if (acc[j] >= acc[max]) max = j;
}
max++;
Database.UpdateSessionCluster(s_id, max); //update the session with its new assigned cluster
}
}
Bảng cấu trúc, dữ liệu thử nghiệm và kết quả dự kiến
EDIT # 2: thêm một dữ liệu nhỏ hơn thiết lập và thuật toán thêm hương
Dưới đây là một tập hợp dữ liệu nhỏ hơn:
PHIÊN
session id | cluster
abc 0
def 0
ghi 0
jkl 0
mno 0
CỤM
cluster_id | label
1 A
2 B
3 C
4 D
5 E
SESSION_DOCUMENT
id | session_id | document_id
1 abc 1
2 def 5
3 jkl 3
4 ghi 4
5 mno 2
6 def 2
7 abc 5
8 ghi 3
CLUSTER_DOCUMENT
id | cluster_id | document_id
1 1 2
2 1 3
3 2 5
4 3 5
5 3 1
6 4 3
7 5 2
8 5 4
Thuật toán một cách chi tiết
Bước 1: được cụm cho các tài liệu xem bởi phiên
session_id | cluster_id | label | document_id
abc 3 C 1
abc 2 B 5
abc 3 C 5
-----
def 2 B 5
def 3 C 5
def 1 A 2
def 5 E 2
----
ghi 5 E 4
ghi 1 A 3
ghi 4 D 3
----
jkl 1 A 3
jkl 4 D 3
----
mno 1 A 2
mno 5 E 2
Bước 2: đếm xảy ra cụm
session_id | cluster_id | label | occurrence
abc 3 C 2 <--- MAX
abc 2 B 1
----
def 2 B 1
def 3 C 1
def 1 A 1
def 5 E 1 <--- MAX
----
ghi 5 E 1
ghi 1 A 1
ghi 4 D 1 <--- MAX
----
jkl 1 A 1
jkl 4 D 1 <--- MAX
----
mno 1 A 1
mno 5 E 1 <--- MAX
Bước 3 (kết quả cuối cùng): tìm tối đa xảy ra cụm cho mỗi phiên (xem ở trên) và xây dựng tập kết quả cuối cùng (session_id, cluster_id):
session_id | cluster_id
abc 3
def 5
ghi 4
jkl 4
mno 5
CHỈNH SỬA # 3: Làm rõ câu trả lời được chấp nhận
Cả hai câu trả lời đều là chính xác. Cả hai đều cung cấp một giải pháp cho vấn đề. Tôi đã cho Mosty Mostacho câu trả lời được chấp nhận bởi vì trước tiên anh ấy đã đưa ra giải pháp và cung cấp một phiên bản khác của giải pháp với VIEW
. Các giải pháp từ mankuTimma có chất lượng tương tự như Mosty Mostacho của giải pháp. Vì vậy, chúng tôi có hai giải pháp tốt như nhau, tôi chỉ chọn Mosty Mostacho vì anh ấy là người đầu tiên.
Cảm ơn cả hai vì những đóng góp của họ. .
Nếu bạn có thể cung cấp dữ liệu mẫu cho bảng hiện tại và kết quả mong đợi từ dữ liệu mẫu của bạn, chúng tôi sẽ dễ dàng hơn cho chúng tôi –
@MostyMostacho: Tôi đã thêm một số dữ liệu mẫu và kết quả mong đợi. – brozo
+1 cho câu hỏi hay viết – YXD