使用DB2 UDB OLAP函数
使用顺序表打印发票
假设我们需要存储某杂货店一条收银线上的所有销售额。还需要能够打印任何一笔买卖的发票,像这样:
ITEM_NAMEPRICE_PER_ITEM
------------------------------ ------------------------
NESCAFE CLASSIC+6.49000000000000E+000
ENGLISH BAGELS 6-PACK+1.49000000000000E+000
ENGLISH BAGELS 6-PACK+1.49000000000000E+000
由于某些原因,我们选择不在数据库中存储重复的记录。也就是说,我们希望只存储一条记录 ('ENGLISH BAGELS 6-PACK', 1.49, 2) ,而不是两条记录 ('ENGLISH BAGELS 6-PACK', 1.49) 。
不存储重复行通常可以带来更多方便。因此,我们应该使用下面这样的表:
CREATE TABLE SALE_ITEM(
SALE_ID INT NOT NULL,
ITEM_NAME VARCHAR(30) NOT NULL,
ITEM_QUANTITY SMALLINT NOT NULL,
PRICE_PER_ITEM FLOAT NOT NULL);
INSERT INTO SALE_ITEM VALUES
(1, 'NESCAFE CLASSIC', 1, 6.49),
(1, 'ENGLISH BAGELS 6-PACK', 2, 1.49),
(1, 'BABY CARROTS', 3, 0.99);
我们需要编写一个查询,该查询的输出应该是这样的(实际上就是打印一张发票):
ITEM_NAMEPRICE_PER_ITEM
------------------------------ ------------------------
NESCAFE CLASSIC+6.49000000000000E+000
ENGLISH BAGELS 6-PACK+1.49000000000000E+000
ENGLISH BAGELS 6-PACK+1.49000000000000E+000
BABY CARROTS+9.90000000000000E-001
BABY CARROTS+9.90000000000000E-001
BABY CARROTS+9.90000000000000E-001
下面是一个非常简单的查询,这个查询可以实现上述功能:
SELECT ITEM_NAME, PRICE_PER_ITEM FROM SALE_ITEM JOIN NUMBER_SEQ
ON NUMBER_SEQ.NUM <= SALE_ITEM.ITEM_QUANTITY ORDER BY
PRICE_PER_ITEM DESC
注意:在不相等的条件下,联结两个表是完全合法的,像这个例子中就是如此。
如前一章所述,我们也可以通过使用递归来得到所需的结果。在某些情况下,递归或许更加有效。不过,使用了顺序表的代码看上去更简单,更易于理解,并且不必为避免可能由递归招致的无限循环而担忧。因此,在这种情况下,比起使用递归来,使用 ROW_NUMBER 是一种简单的替代方法。
如果不能创建辅助表,那么使用表表达式并生成连续数会比较容易,像这样:
SELECT ITEM_NAME, PRICE_PER_ITEM FROM SALE_ITEM
JOIN
(SELECT ROW_NUMBER() OVER() AS NUM FROM SYSCAT.TABLES) AS NUMBER_SEQ
ON NUMBER_SEQ.NUM <= SALE_ITEM.ITEM_QUANTITY
ORDER BY PRICE_PER_ITEM DESC
结果完全一样,不过性能上慢了一点。
