#sql #sql-server #sql-server-2008
Вопрос:
У меня есть запрос, который возвращает таблицу и основан на значении (если оно существует) Я хочу установить номер строки. У меня есть какое-то решение, но оно выглядит долгим, и я думаю, что могло бы быть проще и меньше кода (лучший вариант) для его обработки. Ниже приведен образец с ожидаемыми результатами:
Если запрос возвращает клиенту значение NULL:
----------------------
Process | Client|
A | NULL |
A | B |
A | B |
A | B |
A | C |
A | C |
A | C |
Результат должен быть:
----------------------
Process | Client| RowNumber
A | NULL | 1
A | B | 2
A | B | 3
A | B | 4
A | C | 2
A | C | 3
A | C | 4
Если запрос возвращается без значения NULL:
----------------------
Process | Client|
A | B |
A | B |
A | B |
A | C |
A | C |
A | C |
Результат должен быть:
----------------------
Process | Client| RowNumber
A | B | 1
A | B | 2
A | B | 3
A | C | 1
A | C | 2
A | C | 3
Ответ №1:
Я не уверен NULL
, следует ли всегда относиться к этому так 'B'
, но вам нужно с этим справиться:
select t.* ,
row_number() over (partition by process, coalesce(client, 'B') order by (select null))
from t
where client is not null;
О, я вижу, вы не устанавливаете NULL
'B'
значение «кому», а добавляете число NULL
» s » к другим значениям. Это тоже довольно просто:
select t.* ,
(row_number() over (partition by process, client order by (select null))
(case when client is null then 0
else sum(case when client is null then 1 else 0 end) over ()
end)
)
from t
where client is not null;
Комментарии:
1. @LBman . . . Это более общий ответ, чем тот, который вы (в настоящее время) приняли, потому что он работает для любого числа
NULL
значений.
Ответ №2:
DROP TABLE if exists mytable;
CREATE TABLE mytable(Process char(1), Client char(1));
INSERT INTO mytable values
('A',null),
('A','B'),
('A','B'),
('A','B'),
('A','C'),
('A','C'),
('A','C');
-- with a NULL value
select
Process,
Client,
ROW_NUMBER() OVER (partition by process,Client order by (select null)) CASE WHEN Client is null THEN 0 else 1 end R
from mytable;
-- without a NULL value
select
Process,
Client,
ROW_NUMBER() OVER (partition by process,Client order by (select null)) R
from mytable
where not client is null;
Комментарии:
1. Спасибо @Luuk, но, как я уже сказал, запрос может возвращаться в некоторых случаях с «нулевым», а иногда и без «нулевого» клиента. Я хочу обработать его в одном запросе select, чтобы он охватывал оба сценария. Я думаю, мы могли бы добавить «когда существует», чтобы проверить и охватить оба сценария
Ответ №3:
…
declare @t table(process varchar(10), client varchar(10));
insert into @t(process, client)
values
('A', null),
('A', 'B'),('A', 'B'),('A', 'B'),
('A', 'C'),('A', 'C'),
('A', ''), ('A', ''), ('A', ' '), ('A', ' '),
('A', 'ZXY'), ('A', 'ZXY'),
('X', 'B'),('X', 'B'),('X', 'B'),
('X', 'C'),('X', 'C');
select *,
row_number() over(partition by process,client order by client)
--if there is a null client per process then add 1 to every non null client
case when client is not null and min(case when client is null then 0 else 1 end) over(partition by process) = 0 then 1 else 0 end
-- case when client is not null and min(isnull(ASCII(client '.'), 0)) over(partition by process) = 0 then 1 else 0 end
as rownumber
from
(
select *
from @t
--where client is not null
) as t;