2

这似乎是一个非常简单的问题,但我想不出一个一次性(对我来说是一次性)SQL 查询,它将采用以下内容并添加一个字段,该字段location number将是第一次运行的 1,第一次运行的DAL2BOS运行,3 用于下一次运行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 |
+---------+--------+-----------+----------+
4

3 回答 3

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) 上,这符合对源表的单次扫描。

于 2012-07-26T03:02:13.557 回答
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
于 2012-07-26T02:14:34.063 回答
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
于 2012-07-26T05:22:28.173 回答