这似乎是一个非常简单的问题,但我无法弄清楚一次性通过(一次通过我的眼睛)SQL查询将采取以下内容并添加一个字段location number
,这将是一个1 DAL
的第一次运行,BOS
运行的第一次运行,以及DAL
的下次运行的第一次运行。我知道如何标记第一个分区(使用两个ROW_NUMBER()
)。
+---------+--------+-----------+----------+
| ITEM_ID | LOT_ID | ORGN_CODE | TRANS_ID |
+---------+--------+-----------+----------+
| 61 | 15161 | DAL | 992342 |
| 61 | 15161 | DAL | 992347 |
| 61 | 15161 | DAL | 1043941 |
| 61 | 15161 | BOS | 1061565 |
| 61 | 15161 | BOS | 1064997 |
| 61 | 15161 | BOS | 1064998 |
| 61 | 15161 | BOS | 1064999 |
| 61 | 15161 | BOS | 1065000 |
| 61 | 15161 | BOS | 1065036 |
| 61 | 15161 | BOS | 1065062 |
| 61 | 15161 | BOS | 1065063 |
| 61 | 15161 | DAL | 1065184 |
| 61 | 15161 | DAL | 1065185 |
| 61 | 15161 | DAL | 1065186 |
| 61 | 15161 | DAL | 1065197 |
| 61 | 15161 | DAL | 1065198 |
| 61 | 15161 | DAL | 1083864 |
| 61 | 15161 | DAL | 1083865 |
+---------+--------+-----------+----------+
答案 0 :(得分:5)
试试这样:
SELECT *
, DENSE_RANK() OVER(Order By GroupOrder) As GroupSequence
FROM (
SELECT *,
ROW_NUMBER() OVER(Order By TRANS_ID)
- ROW_NUMBER() OVER(Partition By ORGN_CODE Order By TRANS_ID)
As GroupOrder
FROM yourTable
) As grp
仅一次通过,没有游标。在SQL Server(tsql)上,这符合源表的单次扫描。
答案 1 :(得分:3)
我在Postgresql上运行了这个。也许你可以申请你的rdbms。我们的想法是使用分析函数来确定先前记录的orgn_code。然后用0或1标记每一行,如果它的代码分别与前一行相同或不同。对此列求和会给出递增的数字。
create table transaction( ITEM_ID int, LOT_ID int, ORGN_CODE text, TRANS_ID int);
insert into transaction values(61, 1561, 'DAL', 992342 );
insert into transaction values(61, 1561, 'DAL', 992347 );
insert into transaction values(61, 1561, 'DAL', 1043941 );
insert into transaction values(61, 1561, 'BOS', 1061565 );
insert into transaction values(61, 1561, 'BOS', 1064997 );
insert into transaction values(61, 1561, 'BOS', 1064998 );
insert into transaction values(61, 1561, 'BOS', 1064999 );
insert into transaction values(61, 1561, 'BOS', 1065000 );
insert into transaction values(61, 1561, 'BOS', 1065036 );
insert into transaction values(61, 1561, 'BOS', 1065062 );
insert into transaction values(61, 1561, 'DAL', 1065063 );
insert into transaction values(61, 1561, 'DAL', 1065184 );
insert into transaction values(61, 1561, 'DAL', 1065185 );
insert into transaction values(61, 1561, 'DAL', 1065186 );
insert into transaction values(61, 1561, 'DAL', 1065197 );
insert into transaction values(61, 1561, 'DAL', 1065198 );
insert into transaction values(61, 1561, 'DAL', 1083864 );
insert into transaction values(61, 1561, 'DAL', 1083865 );
SELECT item_id, lot_id, orgn_code, trans_id
,SUM( CASE WHEN orgn_code = previous_orgn_code THEN 0 ELSE 1 END ) OVER(order by item_id, lot_id, trans_id) + 1 AS counter
FROM ( SELECT item_id, lot_id, orgn_code, trans_id
,COALESCE( LAG(orgn_code) OVER(order by item_id, lot_id, trans_id)
,orgn_code ) AS previous_orgn_code
FROM transaction ) x
ORDER BY item_id, lot_id, trans_id, orgn_code;
结果:
61 1561 "DAL" 992342 1
61 1561 "DAL" 992347 1
61 1561 "DAL" 1043941 1
61 1561 "BOS" 1061565 2
61 1561 "BOS" 1064997 2
61 1561 "BOS" 1064998 2
61 1561 "BOS" 1064999 2
61 1561 "BOS" 1065000 2
61 1561 "BOS" 1065036 2
61 1561 "BOS" 1065062 2
61 1561 "DAL" 1065063 3
61 1561 "DAL" 1065184 3
61 1561 "DAL" 1065185 3
61 1561 "DAL" 1065186 3
61 1561 "DAL" 1065197 3
61 1561 "DAL" 1065198 3
61 1561 "DAL" 1083864 3
61 1561 "DAL" 1083865 3
答案 2 :(得分:0)
你走了:
create table transactions( ITEM_ID int, LOT_ID int, ORGN_CODE varchar(10), TRANS_ID int);
insert into transactions values(61, 1561, 'DAL', 992342 );
insert into transactions values(61, 1561, 'DAL', 992347 );
insert into transactions values(61, 1561, 'DAL', 1043941 );
insert into transactions values(61, 1561, 'BOS', 1061565 );
insert into transactions values(61, 1561, 'BOS', 1064997 );
insert into transactions values(61, 1561, 'BOS', 1064998 );
insert into transactions values(61, 1561, 'BOS', 1064999 );
insert into transactions values(61, 1561, 'BOS', 1065000 );
insert into transactions values(61, 1561, 'BOS', 1065036 );
insert into transactions values(61, 1561, 'BOS', 1065062 );
insert into transactions values(61, 1561, 'DAL', 1065063 );
insert into transactions values(61, 1561, 'DAL', 1065184 );
insert into transactions values(61, 1561, 'DAL', 1065185 );
insert into transactions values(61, 1561, 'DAL', 1065186 );
insert into transactions values(61, 1561, 'DAL', 1065197 );
insert into transactions values(61, 1561, 'DAL', 1065198 );
insert into transactions values(61, 1561, 'DAL', 1083864 );
insert into transactions values(61, 1561, 'DAL', 1083865 );
;WITH main as (select ROW_NUMBER() over (order by (select 0)) as sno,ITEM_ID,LOT_ID,ORGN_CODE,TRANS_ID from transactions)
,CTE as (
select sno,ITEM_ID,LOT_ID,ORGN_CODE,TRANS_ID,1 as seq from main where sno=1
union all
select t.sno,t.ITEM_ID,t.LOT_ID,t.ORGN_CODE ,t.TRANS_ID,CASE when c.ORGN_CODE=t.ORGN_CODE then seq else seq+1 end
from main t inner join CTE c on t.sno-1 =c.sno
)
SELECT * FROM CTE