t-sql编号连续分区或运行(字段中相同值的序列)

时间:2012-07-25 23:56:19

标签: sql sql-server database tsql

这似乎是一个非常简单的问题,但我无法弄清楚一次性通过(一次通过我的眼睛)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 |
+---------+--------+-----------+----------+

3 个答案:

答案 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