Найти все пропущенные номера в группе - PullRequest
1 голос
/ 01 апреля 2020

У меня есть этот столбец в моей таблице, и я хочу получить все пропущенные транзакции (это varchar)

  • SA1
  • SA3
  • SA50
  • SA999

Я пытаюсь получить

  • SA2
  • SA4 в SA49
  • SA51 в SA998

РЕДАКТИРОВАТЬ: Я проверил фактические данные, обнаружил, что это не концевые нули.

Я сделал это с PHP. Интересно, есть ли способ в SQL сделать это?

Это может звучать глупо, но я пытаюсь изобразить это так (возвращает нулевые значения)

WITH cte (id) AS (
    SELECT ROW_NUMBER() OVER (ORDER BY s1.[object_id])
    FROM sys.all_columns AS s1
    CROSS JOIN sys.all_columns AS s2
),
table1 AS (
    SELECT sNumber as id1 FROM Sales WHERE sNumber LIKE '%SI_'
),
table2 AS (
    SELECT sNumber as id1 FROM Sales WHERE sNumber LIKE '%SI__'
),
table3 AS (
    SELECT sNumber as id1 FROM Sales WHERE sNumber LIKE '%SI___'
)

SELECT
    'SA' + RIGHT('' + CAST(t1.id AS VARCHAR(2)), 1) AS id_missing
FROM cte t1
LEFT JOIN table1 t2
    ON t1.id = CAST(RIGHT(t2.id1, 1) AS INT)
WHERE
    t1.id < (SELECT MAX(CAST(RIGHT(id1, 1) AS INT)) FROM yourTable1) AND
    t2.id1 IS NULL
UNION ALL

SELECT
    'SA' + RIGHT('' + CAST(t1.id AS VARCHAR(2)), 2) AS id_missing
FROM cte t1
LEFT JOIN table2 t2
    ON t1.id = CAST(RIGHT(t2.id2, 2) AS INT)
WHERE
    t1.id < (SELECT MAX(CAST(RIGHT(id2, 2) AS INT)) FROM yourTable2) AND
    t2.id2 IS NULL
UNION ALL

SELECT
    'SA' + RIGHT('' + CAST(t1.id AS VARCHAR(3)), 3) AS id_missing
FROM cte t1
LEFT JOIN table3 t2
    ON t1.id = CAST(RIGHT(t2.id3, 3) AS INT)
WHERE
    t1.id < (SELECT MAX(CAST(RIGHT(id3, 3) AS INT)) FROM yourTable3) AND
    t2.id3 IS NULL

1 Ответ

3 голосов
/ 01 апреля 2020

Здесь вы можете использовать подход календарной таблицы с левым соединением:

WITH cte (id) AS (
    SELECT ROW_NUMBER() OVER (ORDER BY s1.[object_id])
    FROM sys.all_columns AS s1
    CROSS JOIN sys.all_columns AS s2
)

SELECT
    'SA' + RIGHT('000' + CAST(t1.id AS VARCHAR(3)), 3) AS id_missing
FROM cte t1
LEFT JOIN yourTable t2
    ON t1.id = CAST(RIGHT(t2.id, 3) AS INT)
WHERE
    t1.id < (SELECT MAX(CAST(RIGHT(id, 3) AS INT)) FROM yourTable) AND
    t2.id IS NULL;

screen capture of demo below

Демо

Идея состоит в том, чтобы сгенерировать последовательность чисел, охватывающую возможные до 1000 значений, которые могут отображаться в вашей текущей таблице как SAxxx. Затем мы оставляем присоединение этой таблицы calendar к вашей текущей таблице при условии, что числовая c часть идентификатора не совпадает. Все такие несоответствующие значения SAxxx затем сохраняются в наборе результатов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...