2011-06-01 48 views
0

我有一張表格,裏面包含了用戶的所有照片。出於某種原因(不在乎爲什麼),某些用戶可以從用戶表中刪除(使用DELETE FROM),但照片保留在照片表中。這個MYSQL查詢如何更好

我需要知道用戶表中實際存在的用戶數量。

我想出了第一個解決方案是這樣的:

SELECT COUNT(DISTINCT user_id) FROM photos WHERE user_id IN (SELECT id FROM users) 

但我不知道,如果做兩個查詢是最好的一個。有一個更好的方法嗎?

回答

4

這樣做的最好方法是在兩個表之間使用foriegn鍵約束,並實現級聯刪除。提供更多信息在MySQL手冊:

http://dev.mysql.com/doc/refman/5.5/en/innodb-foreign-key-constraints.html

正如評論者所指出的那樣,這需要使用InnoDB存儲引擎。 This is the default storage engine as of MySQL 5.5.5.

+0

如果您添加需要InnoDB引擎的其他信息,那將會很好。 – RRStoyanov 2011-06-01 20:03:39

+0

我同意在這裏使用foreigns鍵。但由於某種原因,原來這樣做的人並沒有使用它們。 – aseba 2011-06-01 20:03:58

+0

@aseba比你做;) – RRStoyanov 2011-06-01 20:05:29

0

首先,你的查詢會返回由用戶添加的照片中實際存在的用戶表中的號碼 - 而是返回其在至少一個匹配行從用戶表的用戶數照片表。

這個查詢應該是等價的(可能會更好,可能是性能方面更差雖然):

SELECT COUNT(DISTINCT user_id) 
FROM photos, users 
WHERE photos.user_id = users.id 

如果你真的需要存在於用戶表的用戶添加的照片數量:

SELECT COUNT(*) 
FROM photos, users 
WHERE photos.user_id = users.id 

假設您沒有重複的用戶標識符。

+0

'count(*)'總是比'count(some_field)'更快。 – Johan 2011-06-01 20:36:11

1

如果你想知道你有多少個非孤兒圖片,你完全不需要DISTINCT

SELECT COUNT(*) 
FROM users u 
INNER JOIN photos p ON (p.user_id = p.id) 
0

使用此sql查詢。

SELECT COUNT(*) 
    FROM photos p 
     INNER JOIN users u 
      ON p.user_id = u.user_id 
2

級聯刪除的MyISAM

爲了擴大對AJ的答案。如果你不想改變表格。或者你沒有InnoDB表。
您仍然可以級聯刪除。

放在主導表after delete觸發,並把代碼是這樣的:

可以有Y'R魚和熊掌兼得她太

DELIMITER $$ 

CREATE TRIGGER ad_users_each AFTER DELETE ON users FOR EACH ROW 
BEGIN 
    DELETE FROM photos WHERE photos.user_id = old.id; 
END $$ 

DELIMITER ; 

瞧,在級聯刪除MyISAM數據。

它是如何工作的?
觸發後每個成功刪除表用戶中的一行。
觸發器中的old虛擬表在其被刪除之前的值爲users.id。我使用該ID來查找表photos中的所有匹配的user_id,並刪除那些已鏈接到現在已刪除的用戶的鏈接。