Sybase的SQL窗口函数的替代

问题描述 投票:1回答:2

我正在研究Sybase Adaptive Server Enterprise(12.5.0.3版)。尝试使用Row_number() OVER (Partition by columnname order by columnname)。当我执行查询时,它抛出一个异常,表明OVER附近的语法不正确。我已经为sybase数据库搜索了正确的row_number()语法,但是语法没有错。我猜想正在使用的Sybase版本不支持row_number() OVER。我什至尝试了dense_rank() OVER,但遇到了同样的错误。

我需要知道这到底是语法问题还是由于Sybase的低版本不支持关键字?

如果版本存在问题,那么对于sybase数据库,row_number OVER和density_rank()OVER是否有其他选择。

我的查询:

select  cr.firstname, cr.lastname, cr.dob,cr.phone,
          row_number() over (patition by cr.dob order by createddate) "rank"       
          from ff.CrossReferenceTable cr

错误消息:

Server Message:  Number  156, Severity  15
               Server 'MyServer', Line 1:
               Incorrect syntax near the keyword 'over'.
sybase sybase-ase window-functions
2个回答
3
投票

很遗憾,Sybase ASE不支持row_number()功能,也不支持rank()dense_rank()。但是,在一些简单的情况下,如果不使用partition子句,则可以按照

select rank=identity(music), * into #new_temp_tab1 from CrossReferenceTable order by createddate
select firstname, lastname, dob, phone, rank from #new_temp_tab1

在您的情况下,这将变得有些复杂,我建议您将带有临时表的游标用于按行为模拟分区上的row_number()。请看下面的例子:

create table CrossReferenceTable(firstname varchar(50),lastname varchar(50), dob int,phone char(10), createddate date)

create proc sp_CrossReferenceTable
as
begin
declare @i int
declare @cur_firstname varchar(50)
declare @cur_lastname varchar(50)
declare @cur_dob int
declare @cur_phone varchar(10)
declare @cur_rank int
declare cur cursor for select cr.firstname, cr.lastname, cr.dob,cr.phone, count(*) AS "rank" from CrossReferenceTable cr
group by cr.dob ORDER BY cr.dob, createddate
CREATE TABLE #CrossReferenceTable_TEMP(firstname varchar(50),lastname varchar(50), dob int,phone char(10),rank INT)
open cur
fetch cur into @cur_firstname , @cur_lastname , @cur_dob , @cur_phone , @cur_rank
set @i = @cur_rank
while @@SQLSTATUS = 0 
begin
if @i = 0
set @i = @cur_rank
insert into #CrossReferenceTable_TEMP select @cur_firstname , @cur_lastname , @cur_dob , @cur_phone, 
case when @cur_rank > 1 then @cur_rank - (@i - 1) ELSE @cur_rank end as "rank"
set @i = @i - 1
fetch cur into @cur_firstname , @cur_lastname , @cur_dob , @cur_phone , @cur_rank
end
select firstname, lastname, dob, phone, rank from #CrossReferenceTable_TEMP
end

exec sp_CrossReferenceTable

0
投票

尝试使用以下通用查询与ROW_NUMBER()具有相同的效果

SELECT 
  A.MyPartitionColumn, 
  A.MyRunningNumberColumn, 
  ( SELECT count(*) 
    FROM MyTable 
    WHERE    MyPartitionColumn      = A.MyPartitionColumn
         AND MyRunningNumberColumn <= A.MyRunningNumberColumn
  ) AS "Row_Number"
FROM      MyTable  A
ORDER BY  MyPartitionColumn, MyRunningNumberColumn
© www.soinside.com 2019 - 2024. All rights reserved.