T-SQL - получить разрыв между 2 числами - PullRequest
1 голос
/ 01 октября 2019

Я использую SQL Server 2012.

Я получаю «Максимальное число», например, 201900005, которое говорит мне, что диапазон начинается с 201900000 (это дано). Теперь я хочу получить числа, отсутствующие в этом диапазоне.

Я просмотрел несколько вопросов по этому поводу, но, похоже, не могу заставить его работать. Сверка таблицы с самим собой с использованием курсора или между курсором.

Max Number = 201900005, Min Number = 201900000
test_table
+----------------+
|   test_number  |
+----------------+
|   201900001    |
|   201900003    |
|   201900004    |
+----------------+
result
+----------------+
|    missing     |
+----------------+
|   201900000    |
|   201900002    |
|   201900005    |
+----------------+

Текущий процесс работает с таблицей «помощи», которая по существу содержит все числа между 201900000 и 201900005 (aгораздо больше в реальной ситуации) и сравнивает их со значениями в test_table.

Буду благодарен за любые предложения.

Ответы [ 2 ]

1 голос
/ 01 октября 2019

Просто еще один вариант, использующий специальную таблицу подсчета и Union ALL

Пример

Declare @R1 int = 201900000
Declare @R2 int = 201900005

Select Missing = N
 From  (
        Select Top (@R2-@R1+1) N=@R1-1+Row_Number() Over (Order By (Select NULL)) From  master..spt_values n1, master..spt_values n2 
        Union All
        Select test_number from test_table Where test_number between @R1 and @R2
       ) A
 Group By N
 Having count(*)=1

Возвращает

Missing
201900000
201900002
201900005
1 голос
/ 01 октября 2019

Лично я бы использовал Tally для создания списка всех возможных чисел, а затем LEFT JOIN этот список для вашей таблицы и возврата строк, где нет совпадений:

CREATE TABLE dbo.Test_Table (Test_Number int);
INSERT INTO dbo.Test_Table (Test_Number)
VALUES(201900001),(201900003),(201900004);
GO

DECLARE @Start int = 201900000,
        @End int = 201900005;

WITH N AS(
    SELECT N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS(
    SELECT TOP (@End - @Start +1) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) -1 + @Start AS I
    FROM N N1, N N2, N N3) --1000 rows, if you need more, just add more
SELECT T.I
FROM Tally T
     LEFT JOIN dbo.Test_Table TT ON T.I = TT.Test_Number
WHERE TT.Test_Number IS NULL;

GO

DROP TABLE dbo.Test_Table;

DB <> Fiddle

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