SQL - 计算多个表中的引用

时间:2013-12-11 11:30:41

标签: mysql sql

以下是该方案。我有一个名为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技能非常基础。我非常感谢任何能告诉我这是否是一种安全的做事方式的人。

2 个答案:

答案 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子句。