SQL Microsoft Access - PullRequest
       15

SQL Microsoft Access

0 голосов
/ 16 апреля 2011

У меня есть таблица транзакций в Microsoft Access, которая содержит множество транзакций для многих поставщиков. Мне нужно определить, существует ли последовательная нумерация транзакций для каждого поставщика. Я не знаю, какой будет последовательность или количество транзакций на одного поставщика. Мне нужно написать SQL, который идентифицирует последовательную нумерацию для поставщиков и устанавливает поле в «1», если оно присутствует. Я думал о запуске вложенных циклов, которые сначала определяют количество транзакций на одного поставщика, а затем циклы по этим транзакциям, сравнивая номера транзакций. Кто-нибудь может мне помочь с этим ??

Ответы [ 3 ]

0 голосов
/ 16 апреля 2011

Я бы использовал запрос, который находит пробелы в нумерации для любого поставщика, и если он возвращает какие-либо записи, то у вас нет последовательной нумерации для всех поставщиков.

SELECT *
FROM tblTransaction As T1
WHERE (
    SELECT TOP 1 T2.transactionID
    FROM tblTransaction As T2
    WHERE T1.vendorID = T2.vendorID AND
          T1.transactionID < T2.transactionID
    ORDER BY T2.transactionID
) - T1.transactionID > 1

Для каждой записи в таблице выполняется поиск другого идентификатора транзакции с наименьшим номером в той же таблице, которая предназначена для того же поставщика и имеет идентификатор транзакции с более высоким номером, чем первая. Если значение идентификатора транзакции для этой записи более чем на единицу превышает значение в первой записи, это означает разрыв в нумерации для поставщика.

Редактировать: измененные имена переменных выше в соответствии с запросом.

0 голосов
/ 19 апреля 2011

Я не уверен, что это самый простой подход, но я думаю, что он может сработать.Извиняюсь за использование нескольких шагов, но Jet 4.0 заставляет сделать это одним. **

Я предположил, что все значения transactionId являются положительными целыми числами, а последовательность представляет собой набор равномерно расположенных transactionId значений.на vendorId.Кроме того, я предполагаю, что есть ключ на (vendorId, transactionId).

Первый шаг, уничтожить недопустимые строки, например, нужно по крайней мере три строки, чтобы иметь возможность определить последовательность (все остальные строки пройдены или нет?);здесь может также потребоваться отфильтровать другой мусор (например, строки / группы со значениями NULL):

CREATE VIEW tbl1
AS
SELECT T1.vendorId, T1.transactionId
  FROM tbl AS T1
 WHERE EXISTS (
               SELECT T2.vendorId
                 FROM tbl AS T2
                WHERE T2.vendorId = T1.vendorId
                GROUP 
                   BY T2.vendorId
                HAVING COUNT(*) > 2
              );

Найти наименьшее значение для каждого поставщика (пригодится позже):

CREATE VIEW tbl2
AS
SELECT vendorId, MIN(transactionId) AS transactionId_min
  FROM tbl1
 GROUP 
    BY vendorId;

Заставить все последовательности начинаться с нуля (transactionId_base_zero), вычитая наименьшее значение для каждого поставщика:

CREATE VIEW tbl3
AS
SELECT T1.vendorId, T1.transactionId, 
       T1.transactionId - T2.transactionId_min AS transactionId_base_zero
  FROM tbl1 AS T1
       INNER JOIN tbl2 AS T2
          ON T1.vendorId = T2.vendorId;

Прогнозировать значение шага (разность между соседними значениями последовательности) на основе MAX,MIN и COUNT устанавливают значения для каждого поставщика:

CREATE VIEW tbl4
AS
SELECT vendorId, 
       MAX(transactionId_base_zero) / (COUNT(*) - 1)
          AS transactionId_predicted_step
  FROM tbl3;

Проверяют, что прогнозируемое значение шага выполняется для каждого значения последовательности, т. Е. (Псевдокод) this_transactionId - step_value = prior_transactionId (опускается самое низкое transactionId, посколькуу него нет предыдущего значения!):

SELECT DISTINCT T.vendorId
  FROM tbl3 AS T
 WHERE T.transactionId_base_zero > 0
       AND NOT EXISTS (
                       SELECT *
                         FROM tbl3 AS T3
                              INNER JOIN tbl4 AS T4
                                 ON T3.vendorId = T4.vendorId      
                        WHERE T.vendorId = T3.vendorId
                              AND T.transactionId_base_zero 
                                     - T4.transactionId_predicted_step 
                                        = T3.transactionId_base_zero
                      );

Приведенный выше запрос должен вернуть vendorId поставщиков, чьи значения transactionId не являются последовательными.


** В свою защиту, я столкнулся с парой ошибок Jet 4.0, мне пришлось обходить обходной путь.Да, я знаю, что ошибки есть в Jet 4.0 (или его поставщике OLE DB), потому что а) я дважды проверил результаты с помощью SQL Server и б) они не поддаются логике!(даже странная логика 3VL в SQL:)

0 голосов
/ 16 апреля 2011

Чтобы найти один последовательный набор (2 записи, где один номер транзакции следует за другим):

SELECT transactionId FROM tbl WHERE EXISTS 
  (SELECT * FROM tbl as t WHERE tbl.vendorId = t.vendorId 
   AND tbl.transactionId+1 = t.transactionId)
...