2013-12-11 35 views
1

以下是方案。我有一個稱爲模塊的MySQL表,它包含一個或多個條目,每個條目由一個唯一字符串標識 - 模塊ID(mid)。SQL - 計算多個表中的引用

還有一些其他表格(腳本,圖像,集合......),其中包含每個「屬於」其中一個模塊的對象 - 由每個表中的'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' 

這很殷勤地返回這意味着該模塊是「使用」,不能被丟棄。但是,我的SQL技能非常基礎。我非常感謝任何能告訴我這是否是一種安全的做事方式的人。

回答

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 
+0

恐怕,這不起作用 - SQL抱怨「每個派生表都必須有自己的別名」。除此之外,我並不關心有多少模塊引用。我只需要知道該模塊正在使用(0,1),因此我可以阻止其刪除 – DroidOS

+0

是的。抱歉。它最後需要一個別名。我會添加它。如果你想驗證你是否只想知道它是否在那裏,這可能也是最好的,因爲你的查詢返回1,但是如果你從三個表中的一箇中刪除了一個結果,你會得到兩行,一個與0和一個與1 –

+0

謝謝,這是有效的。但是,我不明白你爲什麼在第一個選擇中有一個別名,然後在結束時有一個別名。我從來沒有使用過別名,所以對我來說沒有意義。你的解決方案肯定是更好的,因爲我需要的結果是一個數字,而我的原始SQL將返回一組值。 – DroidOS

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