I am trying to write an SQL Query on a table in MSAccess to add a virtual Column that will add sequential Letters of the Alphabet based on a Value column sorted in Descending order.
------------------------------------------------
| Filename | Zone | ValueCol |
------------------------------------------------
| abc | Zone_MEA | 33 |
| abc | Zone_DEA | 29 |
| abc | Zone_SEO | 21 |
| abc | Zone_GUY | 09 |
|-----------------------------------------------
| def | Zone_SEO | 30 |
| def | Zone_DEA | 22 |
| def | Zone_MEA | 07 |
| def | Zone_GUY | 06 |
|----------------------------------------------|
| ghi | Zone_GUY | 21 |
| ghi | Zone_MEA | 12 |
| ghi | Zone_SEO | 04 |
| ghi | Zone_DEA | 04 |
------------------------------------------------
So all values in ValueCol
sorted in descending order
will receive a sequential letter starting from A per Zone set.
Virtual Col
---------------------------------------------------------------
| Filename | Zone | ValueCol | Letter |
---------------------------------------------------------------
| abc | Zone_MEA | 33 | A |
| abc | Zone_DEA | 29 | B |
| abc | Zone_SEO | 21 | C |
| abc | Zone_GUY | 09 | D |
|-------------------------------------------------------------|
| def | Zone_SEO | 30 | A |
| def | Zone_DEA | 22 | B |
| def | Zone_MEA | 07 | C |
| def | Zone_GUY | 06 | D |
|-------------------------------------------------------------|
| ghi | Zone_GUY | 21 | A |
| ghi | Zone_MEA | 12 | B |
| ghi | Zone_SEO | 04 | C |
| ghi | Zone_DEA | 04 | D |
---------------------------------------------------------------
Is there a way to write such an SQL query in MSAccess without resorting to creating any physical helper tables? (Exception maybe a virtual helper table, but don't know how to create one or how it may be used.)
EDIT: Each section is one particular filename.
Wrote this query on suggestions from @Erik A. Here's the query:
SELECT M.FILENAME, M.ZONE,M.[VALUECOL],
CHR(64 + (
SELECT COUNT(*)
FROM tblTest AS S
WHERE
S.[FILENAME] = M.[FILENAME]
AND S.[ZONE] <= M.[ZONE]
AND S.[VALUECOL] <= M.[VALUECOL]
AND S.[FILENAME]&S.[ZONE]&S.[VALUECOL]<=M.[FILENAME]&M.[ZONE]&M.[VALUECOL]
) ) AS POS
FROM tblTest AS M
GROUP BY M.[FILENAME], M.[ZONE], M.[VALUECOL]
ORDER BY M.[FILENAME] ASC, M.[VALUECOL] DESC,M.[ZONE] ASC
Edit...once again: This takes of point 2 i.e. Duplicates, but not point 1.
SELECT M.FILENAME, M.ZONE,M.[VALUECOL],
CHR(64 + (
SELECT COUNT(*)
FROM tblTest AS S
WHERE
S.[FILENAME] = M.[FILENAME]
AND S.[FILENAME]&S.[ZONE] <= M.[FILENAME]&M.[ZONE]
AND S.[FILENAME]&S.[ZONE]&S.[VALUECOL]<=M.[FILENAME]&M.[ZONE]&M.[VALUECOL]
) ) AS POS
FROM tblTest AS M
GROUP BY M.[FILENAME], M.[ZONE], M.[VALUECOL]
ORDER BY M.[FILENAME] ASC, M.[VALUECOL] DESC,M.[ZONE] ASC
A very general solution for a very general question:
If you have well-defined ordering (you order by a column that doesn't have duplicates) and grouping, you can use a subquery to achieve this:
It would look like this:
SELECT
(
SELECT COUNT(*)
From MyTable s
WHERE
s.GroupingColumn1 = m.GroupingColumn1
AND s.GroupingColumnN = m.GroupingColumnN
AND s.SortingColumn1 <= m.SortingColumn1
)
FROM MyTable m
GROUP BY GroupingColumn1, GroupingColumnN
ORDER BY SortingColumnN
That gets you the position of the items within the groups.
You can easily convert this to capital letters using a little knowledge of the ASCII table (A = position 65, capitals are all sequential, so by incrementing the position by 64 and looking up the ASCII character for the position, you'll get A for 1, B for 2, etc)
Chr(MyPosition + 64)
Of course, if the table is stored in a backend that supports window functions, this can be done more clearly, concisely, and faster. Unfortunately, Access does not support them.
Ordering should be implemented using >
and <
, which makes the statement fairly long for multiple ordering conditions:
SELECT M.[FILENAME], M.[ZONE],M.[VALUECOL],
CHR(64 + (
SELECT COUNT(*)
FROM tblTest AS S
WHERE
(S.[FILENAME] = M.[FILENAME])
AND (
(s.VALUECOL > m.VALUECOL)
OR (
(s.VALUECOL = m.VALUECOL) AND (s.ZONE <= m.ZONE)
)
)
) ) AS LETTER
FROM tblTest AS M
GROUP BY M.[FILENAME], M.[ZONE], M.[VALUECOL]
ORDER BY M.[FILENAME] ASC, M.[VALUECOL] DESC,M.[ZONE] ASC