我有一个包含客户端信息的Access 2010数据库。我需要创建一个每个年龄段的客户数量表。我报告的机构需要一份报告,其中列出了每个年龄段0到100岁的客户数量。下面的SQL查询将创建所需的报告,但不包括零客户端的年龄。
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中不支持的Coalesce功能。
答案 0 :(得分:0)
您可以使用COALESCE
Nz
功能代替
Nz([Age],0)
是的,您的链接应该适合您。
答案 1 :(得分:0)
创建一个包含所有可能整数的'序列'表(英国医疗数据字典中的FYI,我们使用220作为年龄的最大年龄),然后对此表进行“反加入”。您可以使用原始结果的视图。
以下SQL DDL需要ANSI-92查询模式(对于SQL Server编码器可能比默认查询模式更好),但也可以使用Access GUI工具手动创建:
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 );
答案 2 :(得分:0)
系统仅知道存在特定记录的年龄。如果您想要一个介于1..100之间的年龄列表,您需要告诉或提供您正在寻找0..100岁的系统。通过提供您要查找的年龄列表,如果找不到您搜索记录的请求年龄,系统将自动返回0 / null。
正如其他人提到的,您可以将一个包含1..100的表作为行并在SQL中进行比较,或者您可以使用SQL生成数字列表。
某些DBMS提供了一个名为dual的默认表,它有一列和一行,您可以将该表用于任何没有from表的查询。 在您的访问应用程序中,创建一个名为" 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为null /空无结果。 当然,您可以动态扩展或缩短年龄列表。