我正在使用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()
,这很容易实现,但似乎没有。
还有其他优雅的解决方案吗?
答案 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