如何通过 table 中的特定值设置条件行号
How to set Conditional Row Number by specific values from the table
我有一个查询 returns table 并且基于值(如果存在)我想设置 row_number。
我有一些解决方案,但它看起来很长,我认为处理它可能更容易,代码更少(最佳选择)。以下示例具有预期结果:
如果查询 returns Client with NULL:
----------------------
Process | Client|
A | NULL |
A | B |
A | B |
A | B |
A | C |
A | C |
A | C |
OutPut 应该是:
----------------------
Process | Client| RowNumber
A | NULL | 1
A | B | 2
A | B | 3
A | B | 4
A | C | 2
A | C | 3
A | C | 4
如果查询 returns 没有 NULL:
----------------------
Process | Client|
A | B |
A | B |
A | B |
A | C |
A | C |
A | C |
OutPut 应该是:
----------------------
Process | Client| RowNumber
A | B | 1
A | B | 2
A | B | 3
A | C | 1
A | C | 2
A | C | 3
我不确定 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
的数量添加到其他值。这也很简单:
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;
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;
…
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;
我有一个查询 returns table 并且基于值(如果存在)我想设置 row_number。 我有一些解决方案,但它看起来很长,我认为处理它可能更容易,代码更少(最佳选择)。以下示例具有预期结果:
如果查询 returns Client with NULL:
----------------------
Process | Client|
A | NULL |
A | B |
A | B |
A | B |
A | C |
A | C |
A | C |
OutPut 应该是:
----------------------
Process | Client| RowNumber
A | NULL | 1
A | B | 2
A | B | 3
A | B | 4
A | C | 2
A | C | 3
A | C | 4
如果查询 returns 没有 NULL:
----------------------
Process | Client|
A | B |
A | B |
A | B |
A | C |
A | C |
A | C |
OutPut 应该是:
----------------------
Process | Client| RowNumber
A | B | 1
A | B | 2
A | B | 3
A | C | 1
A | C | 2
A | C | 3
我不确定 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
的数量添加到其他值。这也很简单:
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;
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;
…
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;