这个MYSQL查询怎么能更好

时间:2011-06-01 19:58:14

标签: mysql

我有一张桌子,上面有来自用户的所有照片。出于某种原因(不关心原因)可以从users表中删除一些用户(使用DELETE FROM),但照片会保存在照片表中。

我需要知道有多少张照片来自用户桌面上实际存在的用户。

我想出的第一个解决方案是:

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

但我不确定两个查询是否是最好的。有更好的方法吗?

5 个答案:

答案 0 :(得分: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.

答案 1 :(得分:2)

MyISAM中的级联删除

扩展AJ的答案。如果您不想更改表格。或者你没有InnoDB表 您仍然可以进行级联删除。

在前导表上放置一个after delete触发器并将代码放入:

可以拥有蛋糕并且也吃她

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 ;

Voila,在MyISAM中级联删除。

它是如何运作的?
每次成功删除表用户中的行后触发器触发 触发器中的old虚拟表在删除之前保留users.id的值。我使用该ID查找表user_id中所有匹配的photos,并删除那些与现在已删除的用户相关联的{{1}}。

答案 2 :(得分:1)

如果你想知道你有多少非孤儿照片,你根本不需要DISTINCT

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

答案 3 :(得分: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

假设您没有重复的用户ID。

答案 4 :(得分:0)

使用此sql查询。

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