我的下表如下
Country Level Code
USA Level A 10
USA Level A 11
USA Level A 12
USA Level A 13
USA Level A 14
USA Level B 20
USA Level B 21
USA Level B 22
USA Level B 23
USA Level B 24
和
Level Min Code Max Code
Level A 10 15
Level B 20 25
我需要查找表1是否具有表2中定义的范围之间的所有代码,如果缺少某些内容,我希望将其作为查询的输出。请帮忙
如果是以上示例A级15,则缺少B级25
答案 0 :(得分:2)
这是一类可以通过使用“数字表”使用Access SQL解决的问题。这个“数字表”是您在Access中手动创建的表,其中包含一列数值(通常是顺序的),涵盖您将使用的一系列值。
(SQL语言的其他更复杂的实现允许我们“动态”创建这种表,但遗憾的是Access SQL不支持,所以我们必须事先创建表,手动或通过一些VBA代码。)
对于此示例,我们将使用名为[Numbers]的表,其中包含名为[n]的单个Number (Long Integer)
字段。我们需要它覆盖[代码]值的整个预期范围,10到25,所以我们的[Numbers]表将如下所示:
n
--
10
11
12
...
24
25
(请注意,如果“数字表”包含值在预期范围之外通常无关紧要,因为使用它们的查询通常会限制某个WHERE子句中值的范围,但是“数字表”必须完全覆盖预期的值范围。)
一旦我们创建并填充了[Numbers]表,我们就可以从查询
开始SELECT c.Country, c.Level, Numbers.n AS Code
FROM
Numbers,
(SELECT DISTINCT [Country], [Level] FROM Codes) c
INNER JOIN
CodeRanges cr
ON c.Level=cr.Level
WHERE Numbers.n BETWEEN cr.[Min Code] AND cr.[Max Code]
返回规定范围内的所有可能代码
Country Level Code
------- ------- ----
USA Level A 10
USA Level A 11
USA Level A 12
USA Level A 13
USA Level A 14
USA Level A 15
USA Level B 20
USA Level B 21
USA Level B 22
USA Level B 23
USA Level B 24
USA Level B 25
现在我们可以通过使用上面的查询作为派生表(我称之为“AllCodes”)找到[Codes]表中缺少的列表中的项目:
SELECT [Country], [Level], [Code]
FROM
(
SELECT c.Country, c.Level, Numbers.n AS Code
FROM
Numbers,
(SELECT DISTINCT [Country], [Level] FROM Codes) c
INNER JOIN
CodeRanges cr
ON c.Level=cr.Level
WHERE Numbers.n BETWEEN cr.[Min Code] AND cr.[Max Code]
) AllCodes
WHERE NOT EXISTS
(
SELECT * FROM Codes
WHERE Codes.Country=AllCodes.Country
AND Codes.Level=AllCodes.Level
AND Codes.Code=AllCodes.Code
)
返回
Country Level Code
------- ------- ----
USA Level A 15
USA Level B 25
答案 1 :(得分:1)
生成丢失的代码真的很痛苦,特别是在Access中。您需要一个包含所有可能代码的列表,然后找到不在该范围内的代码。在Access中生成这样的列表并不简单。
要查找是否缺少任何内容,您可以算一下:
select r.*
from ranges r left join
(select level, count(distinct code) as NumCodes
from t
) t
on r.level = t.level
where t.NumCodes < (r.MaxCode - r.MinCode)+1