Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Вернуть Id, если distinct по остальным полям таблицы дает 1 запись  [new]
distinct & id
Guest
Здравствуйте.
Возникла такая задача: есть таблица вида:
declare
  @t table (
    id int not null identity primary key,
    a varchar(1) not null,
    b varchar(1) not null
  );

Требуется, если все значения полей a и b одинаковы, вывести одну запись, где в качестве id 0, и уникальные значения a и b, а если значения a и b хотя бы в одной записи отличаются от прочих - вывести все записи с реальным значением id, и соответствующими значениями a и b. Пока придумал вот такое:
declare
  @t table (
    id int not null identity primary key,
    a varchar(1) not null,
    b varchar(1) not null
  );
insert into @t(a, b) values('a','b'),('a', 'c');
select distinct
  case when (select count(*) from (select distinct a, b from @t) v)=1 then 0 else id end id,
  a, b
from @t

- может, это можно сделать как-то изящнее?
5 фев 18, 09:12    [21165602]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть Id, если distinct по остальным полям таблицы дает 1 запись  [new]
Павел Воронцов
Member

Откуда: Новосибирск
Сообщений: 2382
Блог
distinct & id,

select case when t.cnt > 0 then 0 else (select min(t1.id) from @t t1 where t1.a=t.a and t1.b=t.b) end as id,
t.a,
t.b
from (select count(*) as cnt, a, b from @t group by a,b) t
5 фев 18, 11:14    [21166060]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть Id, если distinct по остальным полям таблицы дает 1 запись  [new]
Павел Воронцов
Member

Откуда: Новосибирск
Сообщений: 2382
Блог
Павел Воронцов,

> 1 конечно
5 фев 18, 11:26    [21166148]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть Id, если distinct по остальным полям таблицы дает 1 запись  [new]
Kopelly
Member

Откуда: Красноярск
Сообщений: 289
Павел Воронцов,
Разве что:
case when (select count(distinct a)+count(distinct b) from @t)=2 then 0 else id end id,
6 фев 18, 05:32    [21168786]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть Id, если distinct по остальным полям таблицы дает 1 запись  [new]
invm
Member

Откуда: Москва
Сообщений: 9114
distinct & id
может, это можно сделать как-то изящнее?
Критерии изящности сугубо индивидуальны :)
with t as
(
 select
  id, a, b,
  rank() over (order by a, b) r1,
  rank() over (order by a desc, b desc) r2,
  row_number() over (order by (select 1)) as rn
 from
  @t
)
select
 case when r1 = r2 then 0 else id end as id, a, b
from
 t
where
 (rn = 1 and r1 = r2) or (r1 <> r2);
6 фев 18, 10:11    [21169029]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть Id, если distinct по остальным полям таблицы дает 1 запись  [new]
Kopelly
Member

Откуда: Красноярск
Сообщений: 289
invm,
У тебя пропадает значение "посередине" при нечетном количестве уникальных сочетаний a и b (выполняется условие r1=r2).
Например при
insert into @t(a, b) values('a','b'),('a', 'c'),('b', 'c');

Получаем:
idab
3bc
1ab
6 фев 18, 11:09    [21169197]     Ответить | Цитировать Сообщить модератору
 Re: Вернуть Id, если distinct по остальным полям таблицы дает 1 запись  [new]
invm
Member

Откуда: Москва
Сообщений: 9114
Kopelly
У тебя пропадает значение "посередине" при нечетном количестве уникальных сочетаний
Да, вы правы. Спасибо.

Сделаем иначе:
with t as
(
 select
  id, a, b,
  count(*) over (partition by a, b) c1,
  count(*) over () c2,
  row_number() over (order by (select 1)) as rn
 from
  @t
)
select
 case when c1 = c2 then 0 else id end as id, a, b
from
 t
where
 (rn = 1 and c1 = c2) or (c1 <> c2);
6 фев 18, 12:41    [21169575]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить