#sql-server #tsql #sql-server-2012
#sql-server #tsql #sql-server-2012
Вопрос:
Я написал запрос для извлечения символов сотрудников для определенного диапазона дат.. что дало такой результат
Name Type Date Code
---- ---- -------- ---
Mark Dev 25/02/2014 a
Mark Dev 26/02/2014 b
Mark Dev 27/02/2014 c
Mark Dev 28/02/2014 a
Mark Dev 29/02/2014 b
Mark Dev 30/02/2014 c
Rob Dev 25/02/2014 c
Rob Dev 26/02/2014 a
Rob Dev 27/02/2014 b
Rob Dev 28/02/2014 b
Rob Dev 29/02/2014 c
Rob Dev 30/02/2014 a
Pete Dev 25/02/2014 a
Pete Dev 26/02/2014 a
Pete Dev 27/02/2014 a
Pete Dev 28/02/2014 a
Pete Dev 29/02/2014 b
Pete Dev 30/02/2014 c
Я хотел бы заменить первое вхождение ‘b’ [code] и последнее вхождение ‘b’ на ‘x’ для каждого сотрудника..
Мой запрос выглядит следующим образом..
Select e.Name
,e.Type
,l.Date
,lc.Code
From
Employee e
Inner Join leave l on e.empid = l.empid
Inner Join leaveCode lc on lc.lcodeid = l.lcodeid
order by e.identfier,l.date
Итак, как я могу выбрать все данные, заменив первое и последнее вхождение ‘b’..
Я пробовал..
Select
data.Name,
data.Type,
data.Date,
(CASE WHEN ((Select TOP 1 data.Date from data where data.code = 'b') = data.Date) THEN 'x' END) AS Code
From
(Select e.Name
,e.Type
,l.Date
,lc.Code
From
Employee e
Inner Join leave l on e.empid = l.empid
Inner Join leaveCode lc on lc.lcodeid = l.lcodeid
order by e.identfier,l.date) as data
Комментарии:
1. Вы хотите заменить их в таблице или в результате запроса?
2. Привет, спасибо за ответ.. Я хочу заменить их в результате запроса.. На самом деле я хочу получить свой результат, поскольку я получил свой предыдущий запрос, но заменил первое и последнее вхождения ‘b’ для каждого сотрудника
Ответ №1:
Я бы добавил a row_number()
к каждой строке, разделенной по имени, упорядоченной по дате.
Это дает каждой строке для метки, например, число 1-6.
Затем вы запрашиваете min/max
идентификатор по имени where type='x'
и присоединяете его к исходным данным.
declare @data table (Name nvarchar(100), Type nvarchar(10), Date date, Code nvarchar(1))
insert into @data
select 'Mark', 'Dev', '2014-04-25', 'a' union all
select 'Mark', 'Dev', '2014-04-26', 'b' union all
select 'Mark', 'Dev', '2014-04-27', 'c' union all
select 'Mark', 'Dev', '2014-04-28', 'a' union all
select 'Mark', 'Dev', '2014-04-29', 'b' union all
select 'Mark', 'Dev', '2014-04-30', 'c' union all
select 'Rob', 'Dev', '2014-04-25', 'c' union all
select 'Rob', 'Dev', '2014-04-26', 'a' union all
select 'Rob', 'Dev', '2014-04-27', 'b' union all
select 'Rob', 'Dev', '2014-04-28', 'b' union all
select 'Rob', 'Dev', '2014-04-29', 'c' union all
select 'Rob', 'Dev', '2014-04-30', 'a' union all
select 'Pete', 'Dev', '2014-04-25', 'a' union all
select 'Pete', 'Dev', '2014-04-26', 'a' union all
select 'Pete', 'Dev', '2014-04-27', 'a' union all
select 'Pete', 'Dev', '2014-04-28', 'a' union all
select 'Pete', 'Dev', '2014-04-29', 'b' union all
select 'Pete', 'Dev', '2014-04-30', 'c'
;with rowid as (
select row_number() over(partition by name order by name, date) as id,
*
from @data)
select t1.*
case when t1.id=filter.minid then 'first x' else null end as [firstreplace],
case when t1.id=filter.maxid then 'last x' else null end as [lastreplace]
from rowid t1
join (select min(id) as minid, max(id) as maxid, name from rowid where code='b' group by name) as filter
on t1.name=filter.name
and (t1.id=filter.minid or t1.id=filter.maxid)
Если вам нужно минимальное значение, просто уберите максимальное значение из строки and (t1.id=filter.minid *or t1.id=filter.maxid*)
и наоборот..
Комментарии:
1. Похоже, что этот запрос не возвращает никаких «x». Я что-то упускаю?
2. Я подумал, что, показывая ему первые / последние события для каждого имени, он может обновить его, но никогда не помешает добавить его.