Reputation: 803
I have a following table as below
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
and
Level Min Code Max Code
Level A 10 15
Level B 20 25
I need to find if Table 1 has all the codes between the range defined in Table 2, if some thing is missing, i want that to an output of a query. Please help
In case of above example Level A 15, Level B 25 is missing
Upvotes: 1
Views: 1976
Reputation: 123484
This is a class of problem that can be solved with Access SQL by using a "numbers table". This "numbers table" is a table you manually create in Access that contains a column of numeric values (usually sequential) covering a range of values that you will be working with.
(Other more sophisticated implementations of the SQL language allow us to create this sort of table "on the fly", but unfortunately Access SQL doesn't support that so we have to create the table beforehand, either manually or via some VBA code.)
For this example we'll use a table named [Numbers] with a single Number (Long Integer)
field named [n]. We need it to cover the entire expected range of [Code] values, 10 through 25, so our [Numbers] table will look like this:
n
--
10
11
12
...
24
25
(Note that it usually doesn't matter if a "numbers table" contains values outside expected range, since the queries that use them often limit the range of values in a WHERE clause someplace, but it is imperative that the "numbers table" completely covers the expected range of values.)
Once we have created and populated our [Numbers] table we can start with the query
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]
which returns all possible codes within the prescribed ranges
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
Now we can find the items in the [Codes] table that are missing from that list by using the above query as a derived table (which I will call "AllCodes"):
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
)
which returns
Country Level Code
------- ------- ----
USA Level A 15
USA Level B 25
Upvotes: 2
Reputation: 1269693
Generating the missing codes is a real pain, especially in Access. You need a list of all possible codes, and then find the ones that are not in the range. Generating such a list is not trivial in Access.
To find if anything is missing, you can just count:
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
Upvotes: 1