2016-09-30 87 views
0

我有一個包含客戶端信息的Access 2010數據庫。我需要創建一個每個時代的客戶數量表。我要報告的機構需要報告每個年齡從0到100歲的客戶數量。下面的SQL查詢將創建所需的報表,但不包括具有零客戶端的年齡。如何在Access查詢結果中包含空行

SELECT AgeNum & " years" AS [Age], Count(*) AS [Count] 
FROM (SELECT Int(DateDiff("d", Clients.dob, now())/365.25) AS AgeNum 
FROM Clients) AS [%$##@_Alias] 
GROUP BY [%$##@_Alias].AgeNum; 

如何讓查詢返回Count列中0的空行?

我環顧四周,發現這一點:

How can I create a row for values that don't exist and fill the count with 0 values?

他們創造價值的一個表中查找空組。這是非常相似,我需要的只是它什麼使用不是在Access支持的凝聚功能,2010年

+0

'%$ ## @ _ Alias'有趣的名字選擇! – onedaywhen

回答

0

系統知道存在某個特定記錄的年齡。如果你想有一個年齡在1到100之間的列表,你需要告訴或提供你正在尋找0..100年齡的系統。通過提供您正在查找的年齡列表,如果在查找到的記錄中未找到請求的年齡,系統將自動返回0/null。

正如其他人提到的,你可以有一個1..100行的表格,並在你的SQL中進行比較,或者你可以用SQL生成一個數字列表。

某些DBMS提供了一個名爲dual的默認表,它具有一列和一行,您可以將該表用於任何沒有表的表。 在您的訪問應用程序中,創建一個名爲「dual」的表並插入一行

現在執行這個查詢:

SELECT TMain.counter 
FROM (SELECT (T2.mAge*t3.mFactor10)+t1.mAge AS counter 
FROM (select 1 as mAge from dual 
union all select 2 from dual 
union all select 3 from dual 
union all select 4 from dual 
union all select 5 from dual 
union all select 6 from dual 
union all select 7 from dual 
union all select 8 from dual 
union all select 9 from dual 
union all select 10 from dual) AS T1, 
(select 0 as mAge from dual 
union all select 1 from dual 
union all select 2 from dual 
union all select 3 from dual 
union all select 4 from dual 
union all select 5 from dual 
union all select 6 from dual 
union all select 7 from dual 
union all select 8 from dual 
union all select 9 from dual 
union all select 10 from dual) AS T2, 
(select 10 as mFactor10 from dual) AS T3) AS TMain 
WHERE (((TMain.counter) Between 1 And 100)); 

這將從1..100產生100行。

然後,您可以將此結果用作SQL的外部表,並查找/計算年齡在此列表中的任何人。 邏輯是:

select all age 
from the reqeusted age list 
find and count/return all matched records or return 0 if no records found. 

在SQL中,這將是這樣的,

SELECT TMain.counter as Age, 
(SELECT Count(*) AS [Count] 
FROM (SELECT Int(DateDiff("d", Clients.dob, now())/365.25) AS AgeNum 
FROM Clients) AS [%$##@_Alias] 
WHERE (TMain.counter = [%$##@_Alias].ageNum) 
GROUP BY [%$##@_Alias].AgeNum) as number_of_clients 
FROM (SELECT (T2.mAge*t3.mFactor10)+t1.mAge AS counter 
FROM (select 1 as mAge from dual 
union all select 2 from dual 
union all select 3 from dual 
union all select 4 from dual 
union all select 5 from dual 
union all select 6 from dual 
union all select 7 from dual 
union all select 8 from dual 
union all select 9 from dual 
union all select 10 from dual) AS T1, 
(select 0 as mAge from dual 
union all select 1 from dual 
union all select 2 from dual 
union all select 3 from dual 
union all select 4 from dual 
union all select 5 from dual 
union all select 6 from dual 
union all select 7 from dual 
union all select 8 from dual 
union all select 9 from dual 
union all select 10 from dual) AS T2, 
(select 10 as mFactor10 from dual) AS T3) AS TMain 
WHERE (((TMain.counter) Between 1 And 100)); 

這將產生:從1..100年齡以及客戶端的數量各年齡和null爲空/空無結果。 當然,您可以動態擴展或縮短年齡列表。

+0

這工作得很好。但是,我需要爲所有空白行添加零。謝爾蓋S建議Nz功能。我嘗試在這一行添加它: –

+0

只是封裝了整個子查詢.. nz((select count(.....),0)as ageNum @BeakerMcChemist –

+0

這很好用,但是,我需要添加所有空白行都爲零,因爲我們要報告的代理對格式化的方式非常嚴格。@ Sergey-S和@oneday當我們提供了Nz函數時,我嘗試在這一行添加它:'GROUP BY [Alias] .AgeNum)as number_of_clients'我把它改成了GROUP BY Nz([Alias] .AgeNum,0))作爲number_of_clients',但它不起作用。查詢輸入由Access生成的報告。這是我第一次使用Access。我被選中是爲了這樣做,因爲我「知道電腦」,但我已經超出了我的頭腦。 –

0

你可以用它代替COALESCENz功能:

Nz([Age],0) 

是的,你的鏈接應該工作您。

+1

TC說,他與Access一起工作,他需要查詢。在Access查詢中支持Nz finction –

+0

「在Access查詢中支持Nz finction」 - 不嚴格正確:只有在Access用戶界面中執行該查詢時,Access查詢才支持Nz表達式(在嚴格意義上不是用於查詢的函數)。他們說正在使用「Access 2010數據庫」,然後暗指「所需報告」,但沒有明確說明他們正在使用Access UI。你可能假設正確,但:) – onedaywhen

0

創建一個包含所有可能整數的「序列」表(在英國醫學數據字典中使用FYI,我們使用220作爲年限的最大年齡),然後對此表進行「反加入」。您可以使用視圖來獲取原始結果。

下面的SQL DDL需要ANSI-92查詢模式(可能比默認查詢模式在SQL Server編碼器更好),但也可以使用Access GUI工具maually創建:僅

CREATE TABLE Seq (seq INT NOT NULL UNIQUE); 


INSERT INTO Seq VALUES (1); 
INSERT INTO Seq VALUES (2); 
INSERT INTO Seq VALUES (3); 
... 
(you can use Excel to create this script!) 
... 
INSERT INTO Seq VALUES (100); 


CREATE VIEW ClientAgeTallies (AgeInYears, Tally) 
AS 
SELECT dt.AgeInYears, COUNT(*) AS Tally 
    FROM (SELECT INT(DATEDIFF('d', c.dob, NOW())/365.25) AS AgeInYears 
      FROM Clients AS c) AS dt 
GROUP 
    BY dt.AgeInYears; 


SELECT AgeInYears, Tally 
    FROM ClientAgeTallies 
UNION 
SELECT seq AS AgeInYears, 0 AS Tally 
    FROM Seq 
WHERE seq NOT IN (SELECT AgeInYears FROM ClientAgeTallies); 
相關問題