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

подскажите плз, как реализовать такое:
есть справочник клиентов:
create table AllCllients(
id int IDENTITY (1, 1) NOT NULL,
code int, -- код клиента
name varchar(10), -- имя клиента
active int -- активность записи
-- ... тут еще могут быть какие-то поля вроде "Менеджер клиента", "Тип" и т.д.
)

на одном коде может висеть 2-3 записи о клиенте. Т.е. может быть 2 Ивановых с кодом 100. Один из них может быть активен. А могут быть оба неактивны:
idcodenameactive
11Иванов1
21Иванов0
32Петров0
43Сидоров1
53Сидоров0
63Сидоров0


нужно получить клиентов с приоритетом активности. Т.е. в выборку должны попасть активные клиенты (если есть). Если активных записей нет, тогда берем неактивных. В итоге мы должны увидеть всех клиентов (по одной записи на каждого) с приоритетом активности.
Т.е. из приведенной выше таблицы должно получиться такое:
idcodenameactive
11Иванов1
32Петров0
43Сидоров1


Причем если есть 2 активные записи, то должна попасть только одна из них (критерий абсолютно не важен. Можно по старшенству id, например)

Вот для тестов:
insert into AllCllients(id, code, name, active)
values(1, 1, 'Иванов', 1)
insert into AllCllients(id, code, name, active)
values(2, 1, 'Иванов', 0)
insert into AllCllients(id, code, name, active)
values(3, 2, 'Петров', 0)
insert into AllCllients(id, code, name, active)
values(4, 3, 'Сидоров', 1)
insert into AllCllients(id, code, name, active)
values(5, 3, 'Сидоров', 0)
insert into AllCllients(id, code, name, active)
values(6, 3, 'Сидоров', 0)


Пока придумал использовать не селект, а таблицу. Т.е. сначала добавляем активные записи. А потом, если кого-то не хватает, добавляем из неактивных.
create table clients(
id int -- IDENTITY (1, 1) NOT NULL,
code int, -- код клиента
name varchar(10), -- имя клиента
active int -- активность записи
-- ... тут еще могут быть какие-то поля вроде "Менеджер клиента", "Тип" и т.д.
)

insert into Clients
select distinct id, code, name, active
from AllClients
where Active = 1

insert into Clients
select distinct id, code, name, active
from AllClients ac
where Active = 0
and not exists(select 1 from Clients c
where c.code = ac.code)


ПС. я тут в insert'е накосячил с кол-вом записей. Т.е. если есть 2 неактивные, они добавятся обе.
26 май 15, 19:15    [17692657]     Ответить | Цитировать Сообщить модератору
 Re: выборка с приоритетом записей  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31970
нуб987,

create table #AllCllients(
	id int IDENTITY (1, 1) NOT NULL,
	code int, -- код клиента
	name nvarchar(10), -- имя клиента
	active int -- активность записи
	-- ... тут еще могут быть какие-то поля вроде "Менеджер клиента", "Тип" и т.д.
)
--Вот для тестов:
insert into #AllCllients(code, name, active)
values(1, N'Иванов', 1)
insert into #AllCllients(code, name, active)
values(1, N'Иванов', 0)
insert into #AllCllients(code, name, active)
values(2, N'Петров', 0)
insert into #AllCllients(code, name, active)
values(3, N'Сидоров', 1)
insert into #AllCllients(code, name, active)
values(3, N'Сидоров', 0)
insert into #AllCllients(code, name, active)
values(3, N'Сидоров', 0)

--в выборку должны попасть активные клиенты (если есть). Если активных записей нет, тогда берем неактивных. 
--В итоге мы должны увидеть всех клиентов (по одной записи на каждого) с приоритетом активности.
--Причем если есть 2 активные записи, то должна попасть только одна из них 
--(критерий абсолютно не важен. Можно по старшенству id, например)

select id, code, name, active
from (
	select *, row_number() over (partition by name order by active desc, id desc) as n
	from #AllCllients
) as t
where n = 1

drop table #AllCllients
26 май 15, 19:27    [17692708]     Ответить | Цитировать Сообщить модератору
 Re: выборка с приоритетом записей  [new]
AlanDenton
Member [скрыт]

Откуда:
Сообщений: 1004
SELECT t.id, t.code, t.name, t.active
FROM (
	SELECT *, RowNum = ROW_NUMBER() OVER (PARTITION BY t.code ORDER BY t.active DESC)
	FROM dbo.your_table t
) t
WHERE t.RowNum = 1
26 май 15, 19:27    [17692710]     Ответить | Цитировать Сообщить модератору
 Re: выборка с приоритетом записей  [new]
Akina
Member

Откуда: Зеленоград, Москва, Россия
Сообщений: 21249
А точно нужны ID записей? поскольку задача стоИт "любой из них" - предполагаю, что нет. Но тогда вообще подойдёт вульгарное

SELECT code, name, MAX(active) active
FROM AllCllients
GROUP BY code, name
26 май 15, 20:55    [17692994]     Ответить | Цитировать Сообщить модератору
 Re: выборка с приоритетом записей  [new]
Okmor
Member

Откуда:
Сообщений: 132
Читай про OUTER APPLY
26 май 15, 23:55    [17693627]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить