Выберите несуществующие номера из таблицы каждый ID - PullRequest
0 голосов
/ 25 сентября 2019

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

Пример:

CustomerID Group
1          1
3          1
6          1       
4          2
7          2

Я хочу получитьИдентификатор, который не существует, и выберите его следующим образом:

CustomerID Group
2          1       
4          1
5          1
5          2
6          2
....

..

Решение, используемое в cte, не работает должным образом или вставляет данные в первую очередь и не существует, где предложение.

Есть идеи?

Ответы [ 2 ]

0 голосов
/ 25 сентября 2019

Перекрестное соединение 2 рекурсивных CTE для получения всех возможных комбинаций [CustomerID] и [Group], а затем LEFT присоединение к таблице:

declare @c int = (select max([CustomerID]) from tablename);
declare @g int = (select max([Group]) from tablename);
with 
  customers as (
    select 1 as cust
    union all
    select cust + 1 
    from customers where cust < @c
  ),
  groups as (
    select 1 as gr
    union all
    select gr + 1 
    from groups where gr < @g
  ),
  cte as (
    select *
    from customers cross join groups
  )
select c.cust as [CustomerID], c.gr as [Group] 
from cte c left join tablename t
on t.[CustomerID] = c.cust and t.[Group] = c.gr
where t.[CustomerID] is null
and c.cust > (select min([CustomerID]) from tablename where [Group] = c.gr)
and c.cust < (select max([CustomerID]) from tablename where [Group] = c.gr)

См. Демонстрационную версию ,Результаты:

> CustomerID | Group
> ---------: | ----:
>          2 |     1
>          4 |     1
>          5 |     1
>          5 |     2
>          6 |     2
0 голосов
/ 25 сентября 2019

Если вы можете жить с диапазонами, а не списком с каждым, тогда эффективный метод использует lead():

select group_id, (customer_id + 1) as first_missing_customer_id,
       (next_ci - 1) as last_missing_customer_id
from (select t.*,
             lead(customer_id) over (partition by group_id order by customer_id) as next_ci
      from t
     ) t
where next_ci <> customer_id + 1
...