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

Примере:

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 не работает должным образом или сначала вставляет данные и не содержит условия where.

Любые идеи?

0
Leo96 25 Сен 2019 в 15:47

2 ответа

Лучший ответ

Если вы можете жить с диапазонами, а не списком с каждым из них, эффективный метод использует 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
0
Gordon Linoff 25 Сен 2019 в 13:01

Перекрестное соединение 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
forpas 25 Сен 2019 в 19:50