sql 在子集中创建序列号 - apache derby

vel*_*s4j 6 sql derby window-functions

能够使用以下查询生成序列号

CREATE SEQUENCE seqno AS integer
START WITH 1;

SELECT t1.*,
   (NEXT VALUE
    FOR seqno) AS seqno
FROM
  (SELECT l.TRANSACTION_ID,
      l.HSN
   FROM RWLINEITEM l
   WHERE l.TRANSACTION_ID IN ('CS610-20-10003','CS610-20-10002')
   GROUP BY l.TRANSACTION_ID,l.HSN) t1
Run Code Online (Sandbox Code Playgroud)

这给出了结果

sql 输出

要求是通过 Transaction 和 HSN 生成序列号,例如

预期结果

有什么办法可以达到这个结果。使用 derby-10.13.1.1

GMB*_*GMB 3

看来 Derby 并不完全支持标准窗口函数row_number()

模拟这种情况的典型方法是使用子查询来计算有多少行具有相同transaction_id且较小的hsn,如下所示:

select 
    transaction_id, 
    hsn, 
    1 + coalesce(
        (
            select count(*) 
            from rwlineitem l1 
            where l1.transaction_id = l.transaction_id and l1.hsn < l.hsn
        ),
        0
    ) seqno 
from rwlineitem l
where transaction_id in ('CS610-20-10003','CS610-20-10002')
order by transaction_id, hsn
Run Code Online (Sandbox Code Playgroud)

请注意,如果存在重复的(transaction_id, hsn)元组,它们将得到相同的seqno。这与窗口函数的工作原理类似rank()。如果您想要一个唯一的数字,那么您可以尝试添加另一个随机排序标准:

select 
    transaction_id, 
    hsn, 
    1 + coalesce(
        (
            select count(*) 
            from rwlineitem l1 
            where 
                l1.transaction_id = l.transaction_id 
                and (
                    l1.hsn < l.hsn 
                    or (l1.hsn = l.hsn and random() < 0.5)
                )
        ),
        0
    ) seqno 
from rwlineitem l
where transaction_id in ('CS610-20-10003','CS610-20-10002')
order by transaction_id, hsn
Run Code Online (Sandbox Code Playgroud)