如何在Access查询结果中包含空行

时间:2016-09-30 02:21:22

标签: ms-access

我有一个包含客户端信息的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功能。

3 个答案:

答案 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 /空无结果。 当然,您可以动态扩展或缩短年龄列表。