Sybase SQL: 分区上的行号
Sybase SQL: row number over a partition
你能帮帮我吗?我想了解 Sybase ase SQL 的工作原理。
基本上我有这样的查询:
select ClientId,StartDate,EndDate from TableName
我需要创建一个临时的table,我将在其中放置
ClientID = A, StartDate 20180101, 1
ClientID = A, StartDate 20190101, 2
ClientID = A, StartDate 20200101, 3
ClientID = B, StartDate 20180101, 1
ClientID = B, StartDate 20190101, 2
ClientID = C, StartDate 20190101, 1
ClientID = C, StartDate 20200101, 2
你知道怎么制作吗?我环顾四周,但找不到任何 suitable 解决方案(rownum 不起作用并且正在创建
SELECT row_number = identity(32),t.*
INTO #TempTable
不起作用(在这种情况下,我得到 [1,2,3,4,5,6,7] 而不是 [1,2,3,1,2,1,2]
感谢您的帮助!
OP 没有提供 table DDL,也没有提供 insert
语句的示例集,因此有一些假设:
StartDate
是一个 varchar() (为了这个答案;应该能够毫无问题地切换到 date
、datetime
或 datetime
)
所需输出中不需要 EndDate
(根据 OP 的示例输出)
- 组合
(ClientId, StartDate)
是唯一的(否则建议的答案 - 下面 - 将不会生成所需的结果)
示例数据:
create table clients
(ClientId varchar(10) null
,StartDate varchar(10) null
,EndDate varchar(20) null
)
go
insert into clients values ('A', '20180101', null)
insert into clients values ('A', '20190101', null)
insert into clients values ('A', '20200101', null)
insert into clients values ('B', '20180101', null)
insert into clients values ('B', '20190101', null)
insert into clients values ('C', '20190101', null)
insert into clients values ('C', '20200101', null)
go
正如@Impaler 提到的,Sybase ASE 不支持 'window functions' 所以我们需要有点创意。
一个使用自连接的想法:
select c1.ClientId,
c1.StartDate,
count(*) as num
from clients c1
join clients c2
on c1.ClientId = c2.ClientId
and c1.StartDate >= c2.StartDate
group by c1.ClientId, c1.StartDate
order by 1,2
go
ClientId StartDate num
---------- ---------- -----------
A 20180101 1
A 20190101 2
A 20200101 3
B 20180101 1
B 20190101 2
C 20190101 1
C 20200101 2
注意:对于没有有用索引的较大数据集and/or,此查询可能执行不佳,ymmv ...
演示如果 (ClientId, StartDate)
对不唯一会发生什么...
假设我们的数据集如下所示:
insert into clients values ('A', '20180101', null)
insert into clients values ('A', '20190101', null)
insert into clients values ('A', '20200101', null)
insert into clients values ('B', '20180101', null)
insert into clients values ('B', '20190101', null) -- duplicate (ClientId, StartDate)
insert into clients values ('B', '20190101', null) -- duplicate (ClientId, StartDate)
insert into clients values ('C', '20190101', null)
insert into clients values ('C', '20200101', null)
go
建议的查询生成:
ClientId StartDate num
---------- ---------- -----------
A 20180101 1
A 20190101 2
A 20200101 3
B 20180101 1
B 20190101 6 -- oops, only 2 rows for 'B' and the wrong 'num' value for this row
C 20190101 1
C 20200101 2
如果建议的查询在 OP 的环境中不起作用,则 OP 可能需要提供 minimal, reproducible example;特别是,提供示例 create table
和 insert into
语句以充分展示真实数据集。
你能帮帮我吗?我想了解 Sybase ase SQL 的工作原理。
基本上我有这样的查询:
select ClientId,StartDate,EndDate from TableName
我需要创建一个临时的table,我将在其中放置
ClientID = A, StartDate 20180101, 1
ClientID = A, StartDate 20190101, 2
ClientID = A, StartDate 20200101, 3
ClientID = B, StartDate 20180101, 1
ClientID = B, StartDate 20190101, 2
ClientID = C, StartDate 20190101, 1
ClientID = C, StartDate 20200101, 2
你知道怎么制作吗?我环顾四周,但找不到任何 suitable 解决方案(rownum 不起作用并且正在创建
SELECT row_number = identity(32),t.*
INTO #TempTable
不起作用(在这种情况下,我得到 [1,2,3,4,5,6,7] 而不是 [1,2,3,1,2,1,2]
感谢您的帮助!
OP 没有提供 table DDL,也没有提供 insert
语句的示例集,因此有一些假设:
StartDate
是一个 varchar() (为了这个答案;应该能够毫无问题地切换到date
、datetime
或datetime
)
所需输出中不需要 EndDate
(根据 OP 的示例输出)- 组合
(ClientId, StartDate)
是唯一的(否则建议的答案 - 下面 - 将不会生成所需的结果)
示例数据:
create table clients
(ClientId varchar(10) null
,StartDate varchar(10) null
,EndDate varchar(20) null
)
go
insert into clients values ('A', '20180101', null)
insert into clients values ('A', '20190101', null)
insert into clients values ('A', '20200101', null)
insert into clients values ('B', '20180101', null)
insert into clients values ('B', '20190101', null)
insert into clients values ('C', '20190101', null)
insert into clients values ('C', '20200101', null)
go
正如@Impaler 提到的,Sybase ASE 不支持 'window functions' 所以我们需要有点创意。
一个使用自连接的想法:
select c1.ClientId,
c1.StartDate,
count(*) as num
from clients c1
join clients c2
on c1.ClientId = c2.ClientId
and c1.StartDate >= c2.StartDate
group by c1.ClientId, c1.StartDate
order by 1,2
go
ClientId StartDate num
---------- ---------- -----------
A 20180101 1
A 20190101 2
A 20200101 3
B 20180101 1
B 20190101 2
C 20190101 1
C 20200101 2
注意:对于没有有用索引的较大数据集and/or,此查询可能执行不佳,ymmv ...
演示如果 (ClientId, StartDate)
对不唯一会发生什么...
假设我们的数据集如下所示:
insert into clients values ('A', '20180101', null)
insert into clients values ('A', '20190101', null)
insert into clients values ('A', '20200101', null)
insert into clients values ('B', '20180101', null)
insert into clients values ('B', '20190101', null) -- duplicate (ClientId, StartDate)
insert into clients values ('B', '20190101', null) -- duplicate (ClientId, StartDate)
insert into clients values ('C', '20190101', null)
insert into clients values ('C', '20200101', null)
go
建议的查询生成:
ClientId StartDate num
---------- ---------- -----------
A 20180101 1
A 20190101 2
A 20200101 3
B 20180101 1
B 20190101 6 -- oops, only 2 rows for 'B' and the wrong 'num' value for this row
C 20190101 1
C 20200101 2
如果建议的查询在 OP 的环境中不起作用,则 OP 可能需要提供 minimal, reproducible example;特别是,提供示例 create table
和 insert into
语句以充分展示真实数据集。