Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Обработка сгруппированных записей  [new]
Chrus
Member

Откуда:
Сообщений: 4
Привет. Предположим есть таблица


| ID | Name | LastName | IsActive |
-----------------------------------
| 1 | Alex | Black | True |
| 2 | Bob | White | True |
| 3 | Tom | Brown | True |
| 4 | Bob | White | True |
| 5 | Alex | Black | True |

Хочу сгруппировать по Name и LastName, получится


| ID | Name | LastName | IsActive |
-----------------------------------
| 1 | Alex | Black | True |
| 5 | Alex | Black | True |
-----------------------------------
| 2 | Bob | White | True |
| 4 | Bob | White | True |
-----------------------------------
| 3 | Tom | Brown | True |

Теперь для каждой группы я хочу проверить, если у какой-то записи есть запись в таблице Address, для всех других записей этой группы проставить IsActive в False. Таблицы связаны по ID.


| ID | Address|

Группировку можно сделать с помощью GROUP BY, а дальше как быть? Надеюсь, не слишком запутано объяснил.
5 ноя 13, 21:44    [15081319]     Ответить | Цитировать Сообщить модератору
 Re: Обработка сгруппированных записей  [new]
invm
Member

Откуда: Москва
Сообщений: 9633
Chrus
если у какой-то записи есть запись в таблице Address, для всех других записей этой группы проставить IsActive в False
А если у нескольких записей из группы есть адрес, тогда как?
5 ноя 13, 22:13    [15081433]     Ответить | Цитировать Сообщить модератору
 Re: Обработка сгруппированных записей  [new]
qwerty112
Guest
так как-то
update T
set IsActive = false
where exists (select 1 from T t1 inner join Address a on t1.ID=a.ID where T.Name=t1.Name and T.LastName=t1.LastName )


зы
а СУБД у вас точно МС СКЛ ? что это за True / False ??
5 ноя 13, 22:17    [15081457]     Ответить | Цитировать Сообщить модератору
 Re: Обработка сгруппированных записей  [new]
Chrus
Member

Откуда:
Сообщений: 4
invm,

Первую, у которой есть адрес, оставляем Active. Остальным проставляем False.
5 ноя 13, 22:17    [15081459]     Ответить | Цитировать Сообщить модератору
 Re: Обработка сгруппированных записей  [new]
qwerty112
Guest
Chrus
invm,

Первую, у которой есть адрес, оставляем Active. Остальным проставляем False.

тогда немного не то ...
update T
set IsActive = false
where ID <> (select min(t1.ID) from T t1 inner join Address a on t1.ID=a.ID where T.Name=t1.Name and T.LastName=t1.LastName )
5 ноя 13, 22:21    [15081472]     Ответить | Цитировать Сообщить модератору
 Re: Обработка сгруппированных записей  [new]
invm
Member

Откуда: Москва
Сообщений: 9633
declare @t table (id int, Name varchar(30), LastName varchar(30), IsActive varchar(5));
declare @a table (id int, Addr varchar(100));

insert into @t
values
(1, 'Alex', 'Black', 'True'),
(2, 'Bob', 'White', 'True'),
(3, 'Tom', 'Brown', 'True'),
(4, 'Bob', 'White', 'True'),
(5, 'Alex', 'Black', 'True');

insert into @a
values
 (1, 'aadr1'),
 (4, 'aadr2');

with x as
(
 select
  t.IsActive,
  row_number() over (partition by Name, LastName order by case when a.id is null then 1 end, a.id) as rn
 from
  @t t left join
  @a a on a.id = t.id
)
update x set IsActive = 'False' where rn > 1;

select * from @t;
5 ноя 13, 23:11    [15081680]     Ответить | Цитировать Сообщить модератору
 Re: Обработка сгруппированных записей  [new]
Chrus
Member

Откуда:
Сообщений: 4
invm,

Отлично. А как быть, если нужно проверить несколько условий?

Например есть еще таблица телофонных номеров.
| ID | Phone |

И нужно выбрать первую запись из группы, у которой есть номер, а если номера нет ни у кого, то выбрать адрес как в вашем запросе?
6 ноя 13, 15:34    [15085336]     Ответить | Цитировать Сообщить модератору
 Re: Обработка сгруппированных записей  [new]
invm
Member

Откуда: Москва
Сообщений: 9633
Chrus,

Например, делаете представление
create view AttributesExistenceWithPriority
as
select
 ID, 1 as Priority
from
 Phones

union all

select
 ID, 2 as Priority
from
 Addresses;
Запрос тогда будет выглядеть
with x as
(
 select
  t.IsActive,
  dense_rank() over (partition by Name, LastName order by case when a.Priority is null then 1 end, a.Priority, a.id) as r
 from
  Таблица t outer apply
  (select top (1) id, Priority from AttributesExistenceWithPriority where id = t.id order by Priority) a
)
update x set IsActive = 'False' where r > 1;
6 ноя 13, 17:24    [15086276]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить