2017-04-20 56 views
1

首先,我想爲提供這樣一個弱題目道歉;我無法用更好的方式來描述它。MYSQL - 根據一定的條件輸出額外的列

考慮以下幾點:我們有三個表,一個爲users,一個爲records,一個用於ratings。該表是相當不言自明的,但對於數據庫的模式是如下:

+---------------------+ 
| Tables_in_relations | 
+---------------------+ 
| records    | 
| ratings    | 
| users    | 
+---------------------+ 

records表的方案是如下:

+----------+----------------------+------+-----+---------+----------------+ 
| Field | Type     | Null | Key | Default | Extra   | 
+----------+----------------------+------+-----+---------+----------------+ 
| id  | smallint(5) unsigned | NO | PRI | NULL | auto_increment | 
| title | varchar(256)   | NO |  | NULL |    | 
| year  | int(4)    | NO |  | NULL |    | 
+----------+----------------------+------+-----+---------+----------------+ 

users表的方案是如下:

+----------+----------------------+------+-----+---------+----------------+ 
| Field | Type     | Null | Key | Default | Extra   | 
+----------+----------------------+------+-----+---------+----------------+ 
| id  | smallint(5) unsigned | NO | PRI | NULL | auto_increment | 
| email | varchar(256)   | NO |  | NULL |    | 
| name  | varchar(256)   | NO |  | NULL |    | 
| password | varchar(256)   | NO |  | NULL |    | 
+----------+----------------------+------+-----+---------+----------------+ 

ratings表是obviusiusly,其中的評級與record_id和user_id存儲在一起,並作爲關係工作n表。

它的模式是如下:

+----------+----------------------+------+-----+---------+----------------+ 
| Field | Type     | Null | Key | Default | Extra   | 
+----------+----------------------+------+-----+---------+----------------+ 
| id  | smallint(5) unsigned | NO | PRI | NULL | auto_increment | 
| record_id| smallint(5) unsigned | NO | MUL | NULL |    | 
| user_id | smallint(5) unsigned | NO | MUL | NULL |    | 
| rating | int(1)    | NO |  | NULL |    | 
+----------+----------------------+------+-----+---------+----------------+ 

現在,在我的申請,我有一個獲取基於某個關鍵字記錄的搜索功能。輸出結果還應包括某條記錄的平均評分和每條記錄的總評分。這可以通過下面的查詢來實現:

SELECT re.id, re.title, re.year, ROUND(avg(ra.rating)) as avg_rate, 
COUNT(ra.record_id) as total_times_rated 
FROM records re 
LEFT JOIN ratings ra ON ra.record_id = re.id 
GROUP BY re.id; 

,這將給我下面的輸出:

+----+------------------------+------+----------+-------------------+ 
| id | title     | year | avg_rate | total_times_rated | 
+----+------------------------+------+----------+-------------------+ 
| 1 | Test Record 1   | 2008 |  3 |     4 | 
| 2 | Test Record 2   | 2012 |  2 |     4 | 
| 3 | Test Record 3   | 2003 |  3 |     4 | 
| 4 | Test Record 4   | 2012 |  3 |     3 | 
| 5 | Test Record 5   | 2003 |  2 |     3 | 
| 6 | Test Record 6   | 2006 |  2 |     3 | 
+----+------------------------+------+----------+-------------------+ 

問:

現在,來了棘手的部分,至少對我來說。在我的應用程序中,您可以搜索記錄是否登錄,如果登錄,我還想在上述查詢中包含用戶自己的評分值。

我知道我可以通過讀取會話值並根據該值執行相應的查詢來運行條件來檢查用戶是否登錄。我只是不知道如何將某個用戶的個人評價值包含到上述查詢中。

+0

你如何計算用戶的評分?它是所有匹配記錄評級的「SUM」嗎? –

+0

這是個人價值。每次用戶對一條記錄進行評分時,它都會存儲在「收視率」表中(record_id,user_id和實際費率) –

+0

這樣做的目的是用戶可以查看他/她自己的評級值,如果他/根據關鍵字進行記錄。 –

回答

0

您可以通過添加在列SELECT查詢結果中添加用戶的評價:

SELECT re.id, re.title, re.year, ROUND(avg(ra.rating)) as avg_rate, 
COUNT(ra.record_id) as total_times_rated, 
(SELECT rating FROM ratings WHERE user_id = ? AND record_id = re.id) as user_rating 
FROM records re 
LEFT JOIN ratings ra ON ra.record_id = re.id 
GROUP BY re.id; 

我們可以從會議user_id並將它傳遞給這個查詢以生成結果user_rating列。

假設用戶可以對記錄進行多次評分,我已經使用了SUM。如果沒有,我們可以從查詢中刪除它。

更新

如果你不想GROUP BY考慮該值,那麼你可以用現有的查詢到另一個查詢和列添加到它,比如:

SELECT a.id, a.title, a.year, a.avg_rate, a.total_times_rated, 
(SELECT rating FROM ratings WHERE user_id = ? AND record_id = a.id) as user_rating 
FROM (SELECT re.id as id, re.title as title, re.year as year, ROUND(avg(ra.rating)) as avg_rate, 
COUNT(ra.record_id) as total_times_rated 
FROM records re 
LEFT JOIN ratings ra ON ra.record_id = re.id 
GROUP BY re.id) a; 
+0

剛剛嘗試過,返回以下錯誤:'錯誤1242(21000):子查詢返回多於1行'。我認爲這是因爲可以有多個記錄用戶評分,從而給出錯誤。 是的,用戶不能多次對單個記錄進行評分,這就是爲什麼我從您的答案中刪除了SUM。 –

+0

在查詢中增加了一個條件,現在試試? –

+0

好吧,現在如果用戶評價了一條記錄,我會得到'user_rating'值,如果不是,則得到'NULL'。但是,現在它從一條記錄中提取'total_times_recorded'和'avg_rate',並將其輸出到以前沒有發生過的所有記錄上。奇怪... –