2013-03-24 68 views
3

該圖顯示了我的表的結構。第一行是指導老師B給學生D 10分。第二行意味着導師E並沒有給學生D留下任何印記。有關生成新表的SQL問題

enter image description here

怎樣才能下表?我在stackoverflow.com中引用了另一篇文章。然而,我仍然很困惑。

enter image description here

從圖像如上所示,裝置推薦的O,其速率高於或等於7; x表示不推薦,其比率小於7.

例如,教師B給學生D 10分,因此,從圖像的第二行,我們可以看到StudentD列中有一個「o」。 (其他三行數據現在只是隨機分配)

現在,如果我想推薦一位學生作爲輔導老師A.TutorB,C和D的等級(或相似度)分別是0,2和3。

如何生成一個SQL,以便我能夠將速率轉換爲「o」和「x」並計算排名。而且,最重要的是,我想從圖像中推薦StudentH給TutorA。

我應該如何修改上一篇文章中的代碼?而且,如果我上面提到的想法是正確的?

謝謝。

============================================== ==============================

EDITED

我在數據庫中的以下數據。第一行意味着由導師A給studentC給出10個標記。

enter image description here

我把它轉換爲另一個表以更好地理解。 v是Rate的值。

enter image description here

create temporary table ub_rank as 
select similar.NameA,count(*) rank 
from tbl_rating target 
join tbl_rating similar on target.NameB= similar.NameB and target.NameA != similar.NameA 
where target.NameA = "tutorA" 
group by similar.NameA; 

select similar.NameB, sum(ub_rank.rank) total_rank 
from ub_rank 
join ub similar on ub_rank.NameA = similar.NameA 
left join ub target on target.NameA = "tutorA" and target.NameB = similar.NameB 
where target.NameB is null 
group by similar.NameB 
order by total_rank desc; 

select * from ub_rank; 

上面的代碼從Collaborative filtering in MySQL?引用。我有幾個問題。

  1. SQL中有2個部分。我可以從第一部分中選擇*。但是,如果我輸入如上所示的整個SQL,則系統會提示Table 'mydatabase.ub' doesn't exist如何修改代碼?

  2. 該代碼將找到相似性。我應該如何更改代碼,如果標記少於7,則更改爲o,否則更改爲v,並計算給定用戶的相似度?

enter image description here

+0

表中的最後一行是什麼意思?這是StudentD給TutorB給出的「評分」嗎?另外,你的桌子上有多少學生?你真的想爲每個現有的學生提供專欄嗎? – BellevueBob 2013-03-24 21:57:12

+0

@BellevueBob是的,它表示StudentD給TutorB給出的「評分」。上面的第二張圖片顯示了「推薦學生」部分,我使用的數據與第一張圖片的前兩行中的數據類似。另一方面,當我執行推薦導師部分時,我將使用DB表格數據的第三行到最後一行的數據。對於學生人數,我還沒有考慮好。我想我會先嚐試找出表格,然後嘗試限制尺寸。 – HUNG 2013-03-24 22:05:13

回答

0

這是一個真正的評論,但它是一個評論太長。

首先,您不能輕鬆創建具有可變列數的表格。你事先知道列嗎?一般來說,您可以像您在原始表格中所做的那樣表示矩陣。 。 。 「x」和「y」值是列,值位於第三列。

其次,是xo基於從導師到學生的評分,反之亦然?你的問題完全不明確。

三,等級轉換成 「X」 或 「O」,只需使用一個case語句:

select (case when rating >= 7 then 'x' else 'o' end) 

第四,你說從A到B的相似性,C和d是0 ,2和3。我不知道你是如何從你展示的矩陣中得到這個的。如果它是由「×」的重疊,則價值似乎是0,1,和2

我最後的結論是,你並不需要在已有都是因爲你創建一個這樣的矩陣具有正確格式的數據。

1

你的DB模式,其實並不是很容易的工作。

這裏有一個查詢來獲取詳盡的評價表:

SELECT Tutor.Name, Student.Name, 
    CASE WHEN Rating.Rate IS NULL THEN '' 
    WHEN Rating.Rate > 6 THEN 'o' 
    ELSE 'x' END 
FROM (
    SELECT DISTINCT NameB AS Name 
    FROM tbl_rating 
    WHERE RoleB='Tutor' 
    UNION 
    SELECT DISTINCT NameA AS Name 
    FROM tbl_rating 
    WHERE RoleA='Tutor' 
    ORDER BY Name) AS Tutor 
CROSS JOIN (
    SELECT DISTINCT NameB AS Name 
    FROM tbl_rating 
    WHERE RoleB='Student' 
    UNION 
    SELECT DISTINCT NameA AS Name 
    FROM tbl_rating 
    WHERE RoleA='Student' 
    ORDER BY Name) AS Student 
LEFT JOIN tbl_rating AS Rating 
ON Tutor.Name = Rating.NameA 
AND Student.Name = Rating.NameB 
ORDER BY Tutor.Name, Student.Name 

上述查詢的工作方式是從表中提取(別名爲Tutor第一子查詢)所有導師的名單,和所有學生的名單(第二子查詢Student),做產品的兩套獲得導師和學生的所有可能的組合。然後,它的外連接與評價表,關聯發現學生對導師所做的所有收視率,並與NULL不存在評級練習I. ( - 即學生等級導師 - 獲得opposit等級查詢可以通過交換在LEFT JOIN條款NameANameB獲得)。 的CASE變爲數值(或空)的評分爲符號的要求。

對於相似之處,我們需要增加兩個連接:

  • 多了一個上Tutor
  • ,另一個在Rating

從而使:

SELECT T1.Name AS Tutor1 , T2.Name AS Tutor2, 
    SUM(CASE 
    WHEN (R1.Rate > 6 && R2.Rate > 6) || 
       (R1.Rate < 7 && R2.Rate < 7) THEN 1 
    ELSE 0 END) AS SIMILARITY 
FROM (
    SELECT DISTINCT NameB AS Name 
    FROM tbl_rating 
    WHERE RoleB='Tutor' 
    UNION 
    SELECT DISTINCT NameA AS Name 
    FROM tbl_rating 
    WHERE RoleA='Tutor' 
    ORDER BY Name) AS T1 
CROSS JOIN (
    SELECT DISTINCT NameB AS Name 
    FROM tbl_rating 
    WHERE RoleB='Tutor' 
    UNION 
    SELECT DISTINCT NameA AS Name 
    FROM tbl_rating 
    WHERE RoleA='Tutor' 
    ORDER BY Name) AS T2 
CROSS JOIN (
    SELECT DISTINCT NameB AS Name 
    FROM tbl_rating 
    WHERE RoleB='Student' 
    UNION 
    SELECT DISTINCT NameA AS Name 
    FROM tbl_rating 
    WHERE RoleA='Student' 
    ORDER BY Name) AS Student 
LEFT JOIN tbl_rating AS R1 
ON T1.Name = R1.NameA 
AND Student.Name = R1.NameB 
LEFT JOIN tbl_rating AS R2 
ON T2.Name = R2.NameA 
AND Student.Name = R2.NameB 
WHERE Tutor1 < Tutor2 
GROUP BY Tutor1, Tutor2 
ORDER BY Tutor1, Tutor2 

通過提取s可以使這些查詢更加高效在他們自己的表tudents和導師的具體數據,在學生的收視率和導師評級分裂評級表,並使用外鍵:

Table student : Id | Name 
Table tutor: Id | Name 
Table tutor_rating: StudentId | TutorId | Rate 
Table student_rating: StudentId | TutorId | Rate 

和可能tutor_similiarity表,以避免重新計算整個數據集的時候,用幾個觸發器在評級表上更新它(相似性計算然後是增量式的,並且查詢只會轉儲它的內容)。

Table tutor_similarity: TutorId1 | TutorId2 | Similarity 
+0

我認爲我的回答有些不太正確,關於JOIN的某處,但我不能在沒有測試的情況下查明問題。 – didierc 2013-03-24 23:11:14

+0

不需要使用http://stackoverflow.com/questions/2440826/collaborative-filtering-in-mysql中提到的「類似」?實際上,這種方法非常適合我的解決方案,但我有一些額外的條件改變上面,因此,不知道如何修改它。 – HUNG 2013-03-24 23:13:07

+0

對不起,我的回答不正確,我明天再試。 – didierc 2013-03-24 23:44:45

1

從答案無恥借款this previous question,看看這樣做的伎倆:

SET @sql = NULL; 
SELECT 
    GROUP_CONCAT(DISTINCT 
    CONCAT(
     'max(case when NameB = ''', 
     NameB, 
     ''' then (case when rate >= 7 then ''x'' else ''o'' end) else '' '' end) AS ', 
     replace(NameB, ' ', '') 
    ) 
) INTO @sql 
from tbl_rating 
where RoleA = 'Tutor'; 

SET @sql = CONCAT('SELECT NameA, ', @sql, 
' from tbl_rating 
where RoleA = ''Tutor'' 
group by NameA'); 

PREPARE stmt FROM @sql; 
EXECUTE stmt; 
DEALLOCATE PREPARE stmt; 

這裏是a SQL Fiddle

+0

感謝您的大力幫助!我的代碼如何? – HUNG 2013-03-25 02:02:54