HyperSQL分区的row_number()等价

时间:2012-06-20 03:52:06

标签: sql hsqldb openoffice.org

我正在使用OpenOffice Base(HyperSQL)进行一些数据转换,并希望根据前三个字符然后三个数字生成一个customerID字段,以帮助解决冲突。

获取前三个字符没问题:

CustomerID      Customer_Name
AAA             AAA Services
BUS             Business R US
NOR             Northern Exposure
NOR             North Face
NOR             North Shore Supply
ZEB             Zebra Painting

我想得到这个:

CustomerID      Customer_Name
AAA001          AAA Services
BUS001          Business R US
NOR001          Northern Exposure
NOR002          North Face
NOR003          North Shore Supply
ZEB001          Zebra Painting

我可以看到,如果HyperSQL支持row_number(),这很容易实现,但似乎没有。

还有其他优雅的解决方案吗?

3 个答案:

答案 0 :(得分:1)

HyperSQL 2.2.8支持ROWNUM()。您可以将此版本用作外部数据库。请参阅此链接http://hsqldb.org/web/openoffice.html

使用OpenOffice中包含的HSQLDB 1.8.0,您可以分多步完成此操作(在创建前三个字符的列之后)。

UPDATE CUSTOMER SET "CustomerID" = "CustomerID" || '001' 
  WHERE "Customer_Name" IN (
    SELECT MIN("Customer_Name") 
      FROM CUSTOMERS WHERE CHAR_LENGTH("CustomerID") = 3
      GROUP BY "CustomerID"
    )

然后用'002','003'等重复。

答案 1 :(得分:0)

基本上,你要求的是每组有一个等级(在你的情况下,摸索是按CustomerID)。正如@fredt所说,PARTITION BY没有HSQLDB支持(就像MSSQL下的那个......)但你可以做以下事情(如果在顶部添加自动生成的数字 ID字符串一不是一个大的)

Select ID, CustomerID, Customer_Name,
     (Select 1 + Count(*) From Customers
      Where CustomerID = A.CustomerID
         And Id < A.Id) Rank
 From Customers A 

Rank列将为您提供每个gruop的行号

答案 2 :(得分:0)

您也可以在HSQLDB中实现ROWNUM()OVER(PARTITION BY ... ORDER BY ...),但有一些限制。这里的解决方案假定Customer_Name上没有重复,并且Customer_Name不允许有NULL值。

SELECT A.Partition || RIGHT('00' || count(B.Part), 3) AS "CustomerID", Customer_Name
FROM ( SELECT LEFT(Customer_Name,3) AS "Partition", Customer_Name FROM Table ) A
LEFT JOIN ( SELECT LEFT(Customer_Name,3) AS "Partition", Customer_Name FROM Table ) B
    ON A.Customer_Name >= B.Customer_Name AND A.Partition = B.Partition
GROUP BY A.Partition, A.Customer_Name

只是使解决方案更一般一点;当您的唯一订单位于两个字段F1时,F2使用表达式:

ON ( A.F1 = B.F1 AND A.F2 >= B.F2 OR A.F1 > B.F1 ) AND A.Partition = B.Partition