以下是该方案。我有一个名为modules的MySQL表,其中包含一个或多个条目,每个条目由一个唯一的字符串标识 - 模块ID(mid)。
还有一些其他表(脚本,图像,集合......)包含对象,每个对象都“属于”其中一个模块 - 由每个表中的“mid”列标识。
在允许用户删除模块条目之前,我需要检查该操作是否会在任何其他表中留下任何孤立对象。这是一个让这个更清晰的例子
Table modules
mname mid
Mod1 abcd1234
Mod2 wxyz9876
Table scripts
sname mid
A abcd1234
B wxyz9876
Table images
iname mid
A abcd1234
Table sets
sname mid
一个或多个表可能不包含或没有匹配的条目。
我已经编写并测试了一个SQL来处理这个问题。
SELECT COUNT(*) FROM `images` WHERE mid = 'abcd1234'
UNION
SELECT COUNT(*) FROM `sets` WHERE mid = 'abcd1234'
UNION
SELECT COUNT(*) FROM `scripts` WHERE mid = 'abcd1234'
非常有义务返回 1 ,暗示该模块“正在使用”且无法删除。但是,我的SQL技能非常基础。我非常感谢任何能告诉我这是否是一种安全的做事方式的人。
答案 0 :(得分:2)
不是一个好方法。
UNION
没有ALL
会删除重复的结果。如果你有3行返回1,这将给你1 UNION ALL
将使它返回包含每个表的计数的3行,即使它们是重复的。在那之后你SUM
他们,你得到最后的计数。
你应该这样做:
SELECT SUM(cnt) FROM (
SELECT COUNT(*) as cnt FROM `images` WHERE mid = 'abcd1234'
UNION ALL
SELECT COUNT(*) FROM `sets` WHERE mid = 'abcd1234'
UNION ALL
SELECT COUNT(*) FROM `scripts` WHERE mid = 'abcd1234'
) a
答案 1 :(得分:0)
考虑到模块与其他表之间存在一对多关系,您可以围绕以下概念构建一些东西。
select mid
,count(scripts.sname) as scripts
,count(images.iname) as images
,count(sets.sname) as sets
from modules
left join images using(mid)
left join sets using(mid)
left join scripts using(mid)
where mid = 'abcd1234'
group
by mid;
例如,您可以将count(..)添加到一起,或者包含HAVING子句。