2017-05-06 78 views
0

我正在製作通知表。也就是說結構是這樣的:閱讀通知表

notifications:  
+----+------+----------------------+-----------------------------------+-----------+ 
| ID | user | notification   | message       | timestamp | 
+----+------+----------------------+-----------------------------------+-----------+ 
| 1 | 6 | Denied acceptance | You have been denied for...  |   | 
| 2 | 6 | Apreooved acceptance | You have been accepted...   |   | 
| 3 | 0 | Open slots   | there are still open slots for... |   | 
+----+------+----------------------+-----------------------------------+-----------+ 

和表示該通知是由每一個用戶

notifications_read  
+----+------+--------------+-----------+ 
| ID | user | notification | timestamp | 
+----+------+--------------+-----------+ 
| 1 | 6 | 2   |   | 
+----+------+--------------+-----------+ 

讀取如果通知只是針對一個用戶表,有一個用戶ID下的「用戶」在「通知」中 - 如果通知是針對所有人的,我在用戶下插入'0'。

我想做一個查詢,選擇「通知」,即不讀取的行。

我當前的查詢是不正常:

SELECT * 
FROM notifications 
WHERE id NOT IN 
    (SELECT notification 
    FROM notification_read 
    WHERE user = $id) AND user = $id OR user = 0 

因此,對於上面的表格需要與ID 1 & 3,選擇行

感謝您的幫助!

+0

什麼是「不讀」意味着當一個通知是爲所有用戶?您是否只爲特定用戶尋找未讀通知? –

回答

1

如果你想爲特定的用戶未讀通知,那麼你是在正確的軌道上:

SELECT n.* 
FROM notifications n 
WHERE n.id NOT IN (SELECT nr.notification 
        FROM notification_read nr 
        WHERE nr.user = $id) AND 
     (n.user = $id OR n.user = 0); 

我認爲唯一的問題是圍繞OR邏輯括號。

您也可以使用IN這樣寫:

SELECT n.* 
FROM notifications n 
WHERE n.id NOT IN (SELECT nr.notification 
        FROM notification_read nr 
        WHERE nr.user = $id) AND 
     n.user IN (0, $id); 
+0

你的解決方案是promissing ..我會測試它在表中的幾種組合。 –

+0

作品令人驚歎;) –

1
SELECT n.* 
FROM notifications n 
LEFT JOIN notifications_read nr ON nr.notification = n.id 
WHERE 
nr.id IS NULL 

這會給你一個不存在的n個notifications_read表的通知。

左連接將爲您提供通知中的所有行,並從notifications_read連接具有通知ID的行。因此,當您通過nr.id IS NULL篩選時,您將返回notifications中存在的行,但不會返回notifications_read中的行。

另外,LEFT JOIN的表現會更好。

LEFT [OUTER] JOIN可能比等效的子查詢更快,因爲服務器可能能夠更好地進行優化 - 這一事實並非特定於MySQL Server。 https://dev.mysql.com/doc/refman/5.7/en/rewriting-subqueries.html