如何在oracle sql查询中生成行项目编号

时间:2014-02-19 21:11:25

标签: sql oracle

这似乎应该是一个经典的发票项目问题已经解决了,但也许我没有在我的搜索中使用正确的单词。

我正在运行这样的查询(这只是一个简单的例子,我的真实查询要复杂得多,但它会返回相同的结果):

select invoice.inv_num, item.name, item.qty 
 from invoice invoice, item 
 where invoice.inv_num = item.inv_num
 order by invoice.inv_num

我需要生成一个项目编号列,该列对每个项目递增,但每个新发票编号从1开始。因此,例如,我需要最终结果看起来像这样:

inv_num   item_num   name            qty
-------   --------   -------------   ---
111       1          red widgets     10
111       2          blue widgets    5
222       1          green_widgets   7
222       2          red_widgets     16
222       3          black_widgets   10
333       1          blue_widgets    8
333       2          red_widgets     12

我们仍在使用Oracle 9i以防万一。

3 个答案:

答案 0 :(得分:4)

您可以使用oracle rank或row_number分析函数(取决于您希望如何处理重复项/ euqally排名项)。

以下是将第4列item_number添加到查询中的方法:

select invoice.inv_num, item.name, item.qty ,
       row_number() over (partition by inv_num order by qty desc) item_num
 from invoice invoice, item 
 where invoice.inv_num = item.inv_num
 order by invoice.inv_num
  • 计数器会重置每个新的发票号码,因为 partition by子句。
  • 在发票中,排名/项目编号由数量决定(最高 到最低)。
  • 在上面的查询中,rank或row_number将为您的数据提供相同的结果。但如果发票中有多个具有相同数量的项目(10个红色,10个蓝色小部件),则排名将为您提供相同的项目编号,因此在这种情况下,row_number是合适的。

http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions001.htm#i81407

答案 1 :(得分:3)

select invoice.inv_num,
       item.name,
       item.qty,
       row_number() OVER(PARTITION BY invoice.inv_num order by item.qty desc) as item_num
 from invoice invoice, item 
 where invoice.inv_num = item.inv_num
 order by invoice.inv_num

row_number()生成以1开头的数字..然后我们使用PARTITION BY子句重新启动每个* INV_NUM *的序列。并用数量排序编号。

答案 2 :(得分:0)

假设发票的项目名称是唯一的,您可以使用rank()聚合函数:

create table TESTTABLE(inv_num NUMBER,iname VARCHAR2(100 CHAR),qty NUMBER);

insert into TESTTABLE values(111,'red widgets',10);
insert into TESTTABLE values(111,'blue widgets',5);
insert into TESTTABLE values(222,'green_widgets',7);
insert into TESTTABLE values(222,'red_widgets',16);
insert into TESTTABLE values(222,'black_widgets',10);
insert into TESTTABLE values(333,'blue_widgets',8);
insert into TESTTABLE values(333,'red_widgets',12);
commit;

select inv_num, iname, qty ,
 rank() over (PARTITION BY inv_num ORDER BY iname) as item_num
 from TESTTABLE
 order by inv_num;