2011-10-29 60 views
3

在我的網站上,我允許用戶選擇他們喜歡或感興趣的內容。這是使用預定義的下拉菜單完成的,因此每次用戶登錄該網站會獲得與他們具有相同興趣的用戶列表。PHP - MySQL搜索數據庫表返回的結果與百分比匹配

這是通過使用MySQL WHERE子句獲取登錄用戶的興趣(以db爲單位存儲)並與網站上的其他用戶進行匹配來完成的。但是我遇到麻煩的是如何在每個用戶旁邊顯示百分比或得分,以顯示他們與登錄用戶的興趣有多接近。

例如:

  • 用戶1 - 60%的匹配到你的興趣
  • 用戶1 - 30%的匹配到你的興趣
  • 用戶2 - 20%匹配的興趣

每個用戶有5個不同的興趣,如果全部匹配比100%匹配。

表結構的一個示例:

CREATE TABLE IF NOT EXISTS `helloworld` (
    `id` int(9) NOT NULL AUTO_INCREMENT, 
    `like1` varchar(300) NOT NULL, 
    `like2` varchar(300) NOT NULL, 
    `like3` varchar(300) NOT NULL, 
    `name` varchar(300) NOT NULL, 
    PRIMARY KEY (`id`) 
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ; 

例如查詢:

SELECT * FROM helloworld WHERE like1='football' AND like2='art' 

我用COUNT函數的思想,但我不確定?或者我應該使用子查詢?

編輯:我使用PHP的服務器端語言。用戶不能輸入自己的喜歡,必須使用預先定義的列表。

+1

如果我有like1 ='art'和like2 ='football',我會匹配上面的示例查詢嗎? – Sparky

+0

對不起,你不會匹配,因爲藝術總是在like2列不像1。用戶不能輸入或混合他們的喜好,他們必須從預定義列表中選擇(下拉菜單)。該網站是使用PHP和MySQL實施的,如果有幫助的話。 – TheDeveloper

回答

0

以下是我的操作方法。假設$ LIKE1,$ LIKE2和$ LIKE3從當前用戶是值:

SELECT (IF(like1='$like1',1,0) + IF(like2='$like2',1,0) + IF(like3='$like3',1,0))/3*100 match_percent, 
COUNT(id) 
FROM helloworld 
GROUP BY match_percent; 
+0

你有(錯誤地)認爲喜歡將被存儲在同一列 - 這將限制在數據庫中不同喜歡的總數只是5.錯誤! – Bohemian

+0

我應該問海報,但假設不一定是無效的。那麼,每個專欄是否都有可用的選擇,或者每個專欄都有不同的選擇?如果每個都不同,我的代碼很好,否則你需要一個更規範化的解決方案。 – davidethell

+0

正確的所有值是不同的每列。測試你的代碼似乎產生了我期待的結果。但總是返回一個用戶0%出於某種原因.. – TheDeveloper

0

你在用戶和喜歡之間有很多關係。您的表違反了1NF - 您有一個like列的「重複組」。取而代之的是,有一個單獨的協會表來處理這個問題:

create table user_likes (
    user_id int(9) NOT NULL, 
    like_name varchar(300) NOT NULL 
); 

現在你可以使用更簡單的查詢來獲得比賽的計數 - 我把它留給你的工作了:)

提示:您可以使用位掩碼來幫助確定匹配,爲每個不同的like_name指定2個預定義的冪數(help是一個like_names表)。

0

首先,我認爲你需要一個不同的模式。你所擁有的將使你的任務變得非常困難,因爲它不夠靈活。我建議是這樣的:

CREATE TABLE `users` (
    `id`  INT NOT NULL AUTO_INCREMENT, 
    `name`  VARCHAR(300) NOT NULL, 
    PRIMARY KEY (`id`) 
); 

CREATE TABLE `likes` (
    `user`  INT NOT NULL, 
    `interest` VARCHAR NOT NULL, 
    PRIMARY KEY (`user`,`interest`) 
); 

(對不起,我不記得如何設置MySQL中的FK關係,但我相信你能明白這一點很輕鬆了。)

然後,確定的「喜歡」爲每個用戶數:

SELECT COUNT(*) 
FROM users 
JOIN likes ON likes.user=users.id 
WHERE users.name = 'bob'; 

然後確定有多少喜歡兩個用戶的共同點:

SELECT COUNT(*) 
FROM users AS u1 
JOIN likes AS l1 ON (l1.user = u1.id) 
JOIN likes AS l2 ON (l1.interest = l2.interest) 
JOIN users AS u2 ON (l2.user = u2.id) 
WHERE u1.name = 'bob' 
    AND u2.name = 'alice'; 

然後基於這三個數字,你可以根據需要計算你的百分比 - 可能在你的客戶端代碼中,但是如果你願意的話,你可以使用子選擇來完成所有的SQL端。

實施例:

USERS: 
id | name 
----+------- 
    1 | bob 
    2 | alice 

LIKES: 
user | interest 
------+---------- 
    1 | fish 
    1 | baseball 
    2 | fish 
    2 | cooking 
    2 | baseball 

運行爲bobalice所述第一查詢將顯示Bob具有利益,並且Alice有利益。然後運行第二個查詢將顯示他們bob和愛麗絲一起擁有共同的興趣點。

然後,您可以向Bob顯示Alice分享他100%的利益(2/2 = 100%),並且您可以向Alice表明Bob Bob 66%(2/3 = 66%)的利益。

0

你最好在PHP級別檢查一下。考慮到每個用戶的興趣,你可以使用count()對array_intersect()的結果進行評分,以比較訪問者和其他用戶的興趣(http://www.php.net/manual/en/function.array-intersect。 PHP)。如果你允許5個興趣,那將是(5 * count(array_intersect({params})))%。沒有匹配,0%,4場比賽,80%。

0

這將與您現有的架構做:

select 
    t2.id, 
    t2.name 
    sum(
     t1.like1 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5) + 
     t1.like2 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5) + 
     t1.like3 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5) + 
     t1.like4 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5) + 
     t1.like5 in (t2.like1, t2.like2, t2.like3, t2.like4, t2.like5) 
    ) * 20 as percent_match 
from helloworld t1 
left join helloworld t2 on t1.id != t2.id 
group by 1, 2 
order by 3 desc; 

這工作,因爲在MySQL true1 - 總結真相將總計比賽的數量。

+0

使用* 20的目的是什麼?和(t2.like1,t2.like2。t2.like3。t2.like4。t2。中的t1.like2)like5) - 第二行似乎不起作用。你認爲上面的每一個應該分別總結嗎? – TheDeveloper

+0

@TheDeveloper'* 20'用於轉換爲百分比。 SUM()會給出'0'和'5'之間的數字,但是你需要'0'和'100'之間的百分比......因此'* 20'。此外,我有點而不是逗號(即語法錯誤) - 現在就試試。 – Bohemian

+0

語法錯誤仍然存​​在,我無法解決它。錯誤是「檢查與您的MySQL服務器版本相對應的手冊,以便在sum(t1.like1 in(t2.like1,t2.like2,t2.like3,t2.like4,t2.like5)+'在第4行「 – TheDeveloper

相關問題