Доступ к SQL - добавление номера строки в результат запроса для объединения нескольких таблиц

То, что я пытаюсь сделать, довольно просто. Я просто хочу добавить в запрос номер строки. Поскольку это в Access немного сложнее, чем в других SQL, но при нормальных обстоятельствах все еще возможно с использованием таких решений, как DCount или Select Count (*), пример здесь: Как показать номер строки в запросе Access, например ROW_NUMBER в SQL или Доступ к SQL, как сделать приращение в запросе SELECT

Моя проблема

Моя проблема в том, что я пытаюсь добавить этот счетчик в запрос множественного объединения, который упорядочивает поля из множества таблиц.

Исправление проблем

Мой код немного смешон (19 полей, семь из которых являются длинными выражениями, из 9 различных соединенных таблиц и упорядочены по полям из 5 из этих таблиц). Чтобы упростить задачу, у меня есть упрощенный пример запроса ниже:

Пример запроса

SELECT DCount("*","Requests_T","[Requests_T].[RequestID]<=" & [Requests_T].[RequestID]) AS counter, Requests_T.RequestHardDeadline AS Deadline, Requests_T.RequestOverridePriority AS Priority, Requests_T.RequestUserGroup AS [User Group], Requests_T.RequestNbrUsers AS [Nbr of Users], Requests_T.RequestSubmissionDate AS [Submitted on], Requests_T.RequestID
FROM (((((((Requests_T 
    INNER JOIN ENUM_UserGroups_T ON ENUM_UserGroups_T.UserGroups = Requests_T.RequestUserGroup) 
    INNER JOIN ENUM_RequestNbrUsers_T ON ENUM_RequestNbrUsers_T.NbrUsers = Requests_T.RequestNbrUsers) 
    INNER JOIN ENUM_RequestPriority_T ON ENUM_RequestPriority_T.Priority = Requests_T.RequestOverridePriority) 
ORDER BY Requests_T.RequestHardDeadline, ENUM_RequestPriority_T.DisplayOrder DESC , ENUM_UserGroups_T.DisplayOrder, ENUM_RequestNbrUsers_T.DisplayOrder DESC , Requests_T.RequestSubmissionDate;

Если приведенный выше код пытается выбрать поле из таблицы, которая не включена, я прошу прощения - просто поверьте, что поле откуда-то взято (смеется, т.е. одно из других объединений, которые я исключил, просто для запроса). Прекрасным примером этого являются поля .DisplayOrder, используемые в выражении ORDER BY. Это поля из таблицы, которая просто определяет «приоритет» перечисления. Пример: Requests_T.RequestOverridePriority отображается пользователю как вариант со списком «Низкий», «Средний», «Высокий». Поэтому в таблице я присваиваю им числовой приоритет: «1», «2» и «3» для этих опций, соответственно. Таким образом, когда ENUM_RequestPriority_T.DisplayOrder DESC вызывается в order by, все запросы с «высоким» приоритетом будут отображаться над «средним» и «низким». То же самое верно для ENUM_UserGroups_T.DisplayOrder и ENUM_RequestNbrUsers_T.DisplayOrder.

Я также предпочел бы НЕ использовать DCOUNT из-за эффективности, а скорее сделал бы что-то вроде:

select count(*) from Requests_T where Requests_T.RequestID>=RequestID) as counter

Однако из-за выражения «Order By» мой «счетчик» фактически не считает мои результирующие строки последовательно, поскольку оба моих примера привязаны к RequestID.

Примеры результатов

Основываясь на моих фактических результатах запроса, я сделал пример результата запроса выше.

Counter  Deadline   Priority  User_Group  Nbr_of_Users  Submitted_on  RequestID
5        12/01/2016 High      IT          2-4           01/01/2016    5
7        01/01/2017 Low       IT          2-4           05/06/2016    8
10                  Med       IT          2-4           07/13/2016    11
15                  Low       IT          10+           01/01/2016    16
8                   Low       IT          2-4           01/01/2016    9
2                   Low       IT          2-4           05/05/2016    2

Запрос отображает мои результаты в правильном порядке (те, у которых ближайший крайний срок вверху, затем те, у которых наивысший приоритет, затем группа пользователей, затем # пользователей, и, наконец, если все остальное равно, он сортируется по отправке Дата). Однако мои значения "Counter" совершенно неверны! Поле счетчика должно просто вводить +1 для каждой новой строки. Таким образом, при отображении одного запроса в форме для пользователя я мог бы сказать

«Ваш номер: Counter [связанный с RequestID] в очереди на разработку».

Между тем мои результаты:

  1. Не являются последовательными (обратите внимание, что первые четыре отображаются последовательно, а затем последние две строки - нет)! Несмотря на то, что последние две строки имеют более низкий приоритет, чем записи над ними, они получили более низкое значение Counter просто потому, что у них было более низкое значение RequestID.
  2. Они не начинаются с «1» и увеличиваются на +1 для каждой новой записи.

Идеальные результаты

Таким образом, мой идеальный результат сверху был бы следующим:

Counter  Deadline   Priority  User_Group  Nbr_of_Users  Submitted_on  RequestID
1        12/01/2016 High      IT          2-4           01/01/2016    5
2        01/01/2017 Low       IT          2-4           05/06/2016    8
3                   Med       IT          2-4           07/13/2016    11
4                   Low       IT          10+           01/01/2016    16
5                   Low       IT          2-4           01/01/2016    9
6                   Low       IT          2-4           05/05/2016    2

Я избалован PLSQL и другим программным обеспечением, где это было бы автоматически, лол. Это сводит меня с ума! Любая помощь будет принята с благодарностью.

К вашему сведению - я бы предпочел вариант SQL, а не VBA, если это возможно. VBA очень приветствуется и обязательно получит голосование "за", и мое огромное спасибо, если это сработает, но я хотел бы отметить SQL вариант в качестве ответа.


person TMY    schedule 12.10.2016    source источник
comment
Ваш счетчик будет очень сложным, поскольку он должен соответствовать каждому полю в вашем предложении ORDER BY, а они исходят из объединений. Следовательно, ваш подзапрос count должен иметь соединения. Еще более сложным является переключение между ASC и DESC.   -  person Parfait    schedule 12.10.2016
comment
В качестве альтернативы добавьте записи запроса во временную таблицу с помощью автонумерации, а затем запустите подзапрос счетчика (поскольку идентификатор автоматического увеличения может пропускаться из-за изменений данных). Таким образом, ваша корреляция - это всего лишь одна таблица без объединений, но своп все равно становится проблемой.   -  person Parfait    schedule 12.10.2016


Ответы (1)


К сожалению, в MS Access нет очень полезной функции ROW_NUMBER (), как у других клиентов. Так что нам осталось импровизировать.

Поскольку ваш запрос очень сложен, а MS Access не поддерживает общие табличные выражения, я рекомендую вам выполнить двухэтапный процесс. Сначала назовите тот запрос, который вы уже написали IntermediateQuery. Затем напишите второй запрос с именем FinalQuery, который выполняет следующие действия:

SELECT i1.field_primarykey, i1.field2, ... , i1.field_x,
    (SELECT field_primarykey FROM IntermediateQuery i2
     WHERE t2.field_primarykey <= t1.field_primarykey) AS Counter
FROM IntermediateQuery i1
ORDER BY Counter

Прискорбный побочный эффект этого заключается в том, что чем больше данных возвращает ваша таблица, тем больше времени потребуется для вычисления встроенного подзапроса. Однако это единственный способ получить номера строк. Это действительно зависит от наличия первичного ключа в таблице. В этом конкретном случае это не обязательно должен быть явно определенный первичный ключ, это просто должно быть поле или комбинация полей, которые полностью уникальны для каждой записи.

person SandPiper    schedule 18.06.2017