[英]Performing a SELECT Count on multiple tables with specific criteria
我在用於檢查數據准確性的數據庫中有四個表。 [Participants]
有ParticipantID和其他 3 個表[PreForm]
, [PostForm]
, [ServiceForm]
應該具有與[Participants]
相同數量的ParticipantID 。
查詢的最終目標是向每個社區發送有關其每月計數的報告。 如果他們在一定程度上不准確,我們會與他們聯系。 我們通過對表中的 ID 進行計數來實現這一點。
我嘗試的查詢:
SELECT Participants.[community], COUNT(Participants.[ParticipantID]) AS
Part_Count,
COUNT(PreForm.[ParticipantID]) AS Pre_Count,
COUNT(PostForm.[ParticipantID]) AS Post_Count,
COUNT(ServiceForm.[ParticipantID]) AS Service_Count
FROM ((Participants INNER JOIN PreForm ON Participants.[ParticipantID] = PreForm.[ParticipantID])
INNER JOIN PostForm ON Participants.[ParticipantID] = PostForm.[ParticipantID])
INNER JOIN [ServiceForm] ON Participants.[ParticipantID] = [ServiceForm].ParticipantID
WHERE (((Participants.[Date]) Between #10/1/2019# And #11/30/2019#))
GROUP BY Participants.[community];
這個查詢......有什么作用? 計數不准確。 即使使用 LEFT Joins,我也會得到奇怪的計數。 我知道如果這些表被規范化,很多問題都可以解決,但那些不是我拿到的牌。
任何人都可以確定此查詢中發生了什么導致計數不准確? 有一個更好的方法嗎?
編輯:這是一個粗略的創建/插入列表:創建表參與者(ParticipantID TEXT PRIMARY KEY,社區文本); 插入參與者(“QWE”,“美國”); INSERT INTO 參與者(“ASD”、“美國”); INSERT INTO 參與者(“ZXC”、“墨西哥”); CREATE TABLE PreForm (ParticipantID TEXT); 插入 PreForm(“QWE”); 插入預成型件(“ZXC”); CREATE TABLE ServiceForm (ParticipantID TEXT); INSERT INTO ServiceForm ("QWE");
{Participants}
[ID] [Community]
QWE US
ASD US
ZXC Mexico
{PreForm}
[ID]
QWE
ZXC
{ServiceForm}
[ID]
QWE
{Desired Query}
[Community] [Part_Count] [Pre_Count] [Service_Count]
US 2 1 1
Mexico 1 1
由於表的粒度,特別是ParticipantID
的唯一性,計數可能不正確。 如果同一個ParticipantID
可以在任何表中出現多次,那么您的INNER JOIN
捕獲一對多或多對多配對,這將是每個ParticipantID
實例的實際計數的兩倍、三倍、四倍或其他倍數(例如, 18*4=72
, 18*5=90
)。 如果潛在的ParticipantIDs
可以選擇出現在其他表中,您可能希望使用LEFT JOIN
。
為了說明使用您發布的數據和 SQLite(MS Access 的開源文件級數據庫對應物)查看這兩個小提琴(單擊|> 運行以獲得結果):
使用LEFT JOIN
正確計數查詢(使用准確的發布數據)
| Community | Part_Count | Pre_Count | Service_Count |
| --------- | ---------- | --------- | ------------- |
| Mexico | 1 | 1 | 0 |
| US | 2 | 1 | 1 |
不正確計數與查詢LEFT JOIN
(相同的數據,但重復QWE
和ZXC
在PreForm
)
| Community | Part_Count | Pre_Count | Service_Count |
| --------- | ---------- | --------- | ------------- |
| Mexico | 2 | 2 | 0 |
| US | 3 | 2 | 2 |
一種解決方案是在 join 子句中添加另一個字段,以便更好地捕獲唯一性,例如日期,如果沒有ParticipantID
可以在特定日期出現多次,當然如果日期在所有表中都可用。
SELECT p.[community],
COUNT(p.[ParticipantID]) AS Part_Count,
COUNT(pre.[ParticipantID]) AS Pre_Count,
COUNT(post.[ParticipantID]) AS Post_Count,
COUNT(s.[ParticipantID]) AS Service_Count
FROM ((Participants p
LEFT JOIN PreForm pre
ON p.[ParticipantID] = pre.[ParticipantID]
AND p.[Date] = pre.[Date])
LEFT JOIN PostForm post
ON p.[ParticipantID] = post.[ParticipantID]
AND p.[Date] = post.[Date])
LEFT JOIN [ServiceForm] s
ON p.[ParticipantID] = s.ParticipantID
AND p.[Date] = s.[Date]
WHERE (((p.[Date]) Between #10/1/2019# And #11/30/2019#))
GROUP BY p.[community];
如果日期不能充分捕獲不同的記錄,可以添加一個像FormId
這樣的表單指示符,以防ParticipantID
可以在一天內填寫多個但不同的表單(或同時使用表單和日期)。
SELECT p.[community],
COUNT(p.[ParticipantID]) AS Part_Count,
COUNT(pre.[ParticipantID]) AS Pre_Count,
COUNT(post.[ParticipantID]) AS Post_Count,
COUNT(s.[ParticipantID]) AS Service_Count
FROM ((Participants p
LEFT JOIN PreForm pre
ON p.[ParticipantID] = pre.[ParticipantID]
AND p.[FormID] = pre.[FormID])
LEFT JOIN PostForm post
ON p.[ParticipantID] = post.[ParticipantID]
AND p.[FormID] = post.[FormID])
LEFT JOIN [ServiceForm] s
ON p.[ParticipantID] = s.ParticipantID
AND p.[FormID] = s.[FormID]
WHERE (((p.[Date]) Between #10/1/2019# And #11/30/2019#))
GROUP BY p.[community];
注意:如果您添加其他加入字段,那么您正在計算每個Commnity
ParticipantID
和Date
或ParticipantID
和FormId
(不是單獨的ParticipantID
)。
最后,如果您的小型模擬數據顯示沒有其他可用字段,那么這是數據庫設計問題,而不是 SQL 查詢問題。 您必須通過在表格中添加日期、表格或其他一些指示符來相應地重新設計表格,以便更好地捕捉唯一性以進行比較。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.