SQL Запрос в MSAccess для ранжирования столбца значений с буквами на основе порядка сортировки - PullRequest
2 голосов
/ 23 февраля 2020

Я пытаюсь написать SQL Запрос к таблице в MSAccess, чтобы добавить виртуальный столбец, который будет добавлять последовательные буквы алфавита на основе столбца значения, отсортированного в порядке убывания.

------------------------------------------------
|    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      |
---------------------------------------------------------------

Есть ли способ написать такой SQL запрос в MSAccess, не прибегая к созданию каких-либо физических вспомогательных таблиц? (Исключением может быть виртуальная вспомогательная таблица, но не знаете, как ее создать или как ее можно использовать.)

РЕДАКТИРОВАТЬ: Каждый раздел представляет собой одно конкретное имя файла.

Написал этот запрос по предложениям от @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.

enter image description here

Редактировать ... еще раз: Это занимает точку 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

enter image description here

1 Ответ

4 голосов
/ 23 февраля 2020

Очень общее решение для очень общего вопроса:

Если у вас есть четкое упорядочение (вы упорядочиваете по столбцу без дубликатов) и группировка, вы можете использовать подзапрос для достижения этой цели :

Это выглядело бы следующим образом:

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 (A = позиция 65, все заглавные буквы последовательны, поэтому, увеличив позицию на 64 и найдя ASCII-символ для позиции, вы получите A для 1, B для 2, et c )

Chr(MyPosition + 64)

Конечно, если таблица хранится в бэкэнде, который поддерживает оконные функции, это можно сделать более четко, сжато и быстрее. К сожалению, 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
...