我有一张桌子,上面有来自用户的所有照片。出于某种原因(不关心原因)可以从users表中删除一些用户(使用DELETE FROM),但照片会保存在照片表中。
我需要知道有多少张照片来自用户桌面上实际存在的用户。
我想出的第一个解决方案是:
SELECT COUNT(DISTINCT user_id) FROM photos WHERE user_id IN (SELECT id FROM users)
但我不确定两个查询是否是最好的。有更好的方法吗?
答案 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