SQL 在 MS Access 中查询以根据其排序顺序对具有字母的值列进行排名
SQL Query in MSAccess to Rank a Value Column with Letters based on it's Sort Order
我正在尝试在 MSAccess 中对 table 编写一个 SQL 查询,以添加一个虚拟列,该虚拟列将根据按降序排序的值列添加字母表的顺序字母。
------------------------------------------------
| 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 |
------------------------------------------------
因此 ValueCol
中所有在 descending order
中排序的值都将收到一个从每个区域集 A 开始的连续字母。
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 |
---------------------------------------------------------------
有没有一种方法可以在 MSAccess 中编写这样的 SQL 查询,而无需创建任何物理助手 table? (例外可能是虚拟助手 table,但不知道如何创建或如何使用它。)
编辑:每一节都是一个特定的文件名。
根据@Erik A 的建议编写了此查询。这是查询:
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
- 从下面的输出中可以看出,字母顺序仍然不是连续的。
- 还会在特定的 FILENAME 部分中获取重复的字母。
再次编辑...:
这需要第 2 点,即重复,但不是第 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
一个非常普遍的问题的非常普遍的解决方案:
如果您有明确定义的排序(按没有重复的列排序)和分组,您可以使用子查询来实现:
看起来像这样:
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
这会为您提供项目在组中的位置。
您可以使用一点 ASCII 知识轻松将其转换为大写字母 table(A = 位置 65,大写字母都是连续的,因此通过将位置递增 64 并查找 ASCII 字符的位置,你会得到 1 的 A,2 的 B,等等)
Chr(MyPosition + 64)
当然,如果table存储在支持window功能的后台,这样可以做到更清晰、简洁、快捷。不幸的是,Access 不支持它们。
应使用 >
和 <
实现排序,这使得语句对于多个排序条件相当长:
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
我正在尝试在 MSAccess 中对 table 编写一个 SQL 查询,以添加一个虚拟列,该虚拟列将根据按降序排序的值列添加字母表的顺序字母。
------------------------------------------------
| 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 |
------------------------------------------------
因此 ValueCol
中所有在 descending order
中排序的值都将收到一个从每个区域集 A 开始的连续字母。
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 |
---------------------------------------------------------------
有没有一种方法可以在 MSAccess 中编写这样的 SQL 查询,而无需创建任何物理助手 table? (例外可能是虚拟助手 table,但不知道如何创建或如何使用它。)
编辑:每一节都是一个特定的文件名。
根据@Erik A 的建议编写了此查询。这是查询:
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
- 从下面的输出中可以看出,字母顺序仍然不是连续的。
- 还会在特定的 FILENAME 部分中获取重复的字母。
再次编辑...: 这需要第 2 点,即重复,但不是第 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
一个非常普遍的问题的非常普遍的解决方案:
如果您有明确定义的排序(按没有重复的列排序)和分组,您可以使用子查询来实现:
看起来像这样:
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
这会为您提供项目在组中的位置。
您可以使用一点 ASCII 知识轻松将其转换为大写字母 table(A = 位置 65,大写字母都是连续的,因此通过将位置递增 64 并查找 ASCII 字符的位置,你会得到 1 的 A,2 的 B,等等)
Chr(MyPosition + 64)
当然,如果table存储在支持window功能的后台,这样可以做到更清晰、简洁、快捷。不幸的是,Access 不支持它们。
应使用 >
和 <
实现排序,这使得语句对于多个排序条件相当长:
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