SQL Server 2008 R2:ROW_NUMBER()

时间:2014-11-04 10:44:52

标签: sql-server sql-server-2008-r2

我有以下数据:

示例

create table vdata
(
cola varchar(10),
colb varchar(10)
 );

insert into vdata values('A','B'),('B','C'),('A','X'),('Z','L'),
('N','M'),('O','P'),('R','Z'),('X','Y'),('T','N'),('F','E'),('G','H');

看起来像:

select * from vdata;

cola   colb
--------------
A       B
B       C
A       X
Z       L
N       M
O       P  
R       Z
X       Y
T       N
F       E
G       H

注意:现在我只想显示cola colb必须出现的数据> colb必须出现在cola中,我想添加列以根据下一条记录中显示的值显示每条记录的行号。

预期结果

RowNumbers  cola   colb
------------------------
1            A      B
1            A      X
1            B      C
2            N      M
3            R      Z
2            T      N
1            X      Y
3            Z      L    

上述结果的说明:第一行在开始时有rownumber 1,并再次分配给下两条记录,因为column(cola or colb)中的任何一条都有值A or B所以。因为它而给予fouth记录的rownumber 2没有任何值A or B,并且进程将继续相同。请注意,记录7的rownumber为X and Y 1,因为它与A表中记录第2位的A and X相关。

我的不好尝试

SELECT
  row_number() over(PARTITION BY cola order by cola) RowNumbers,
  cola,
  colb
FROM vdata
where cola in (select colb from vdata)
or colb in (select cola from vdata)
ORDER BY    cola,colb

2 个答案:

答案 0 :(得分:3)

您需要在表格中使用某种ID来建立排序

create table #vdata
(
id int identity(1,1),
cola varchar(10),
colb varchar(10)
 );

insert into #vdata values('A','B'),('B','C'),('A','X'),('Z','L'),
('N','M'),('O','P'),('R','Z'),('X','Y'),('T','N'),('F','E'),('G','H');


WITH Roots AS (
    SELECT 1 AS level
         ,id
         ,id AS topid
         ,cola
         ,colb
    FROM #vdata
  UNION ALL
    SELECT level + 1 AS level
          ,#vdata.id
          ,Roots.topid
          ,#vdata.cola
          ,#vdata.colb
    FROM Roots
         INNER JOIN #vdata
             ON (#vdata.id > Roots.id)
                AND (#vdata.cola = Roots.cola
                     OR #vdata.cola = Roots.colb
                     OR #vdata.colb = Roots.cola
                     OR #vdata.colb = Roots.colb)
)
, MaxLevel AS (
    SELECT id 
          ,topid
          ,DENSE_RANK() OVER (ORDER BY topid) AS RowNumbers
          ,cola
          ,colb
    FROM Roots
    WHERE level = (SELECT MAX(level) FROM Roots AS InnerRoots WHERE InnerRoots.id = Roots.id)
)
SELECT RowNumbers
      ,cola
      ,colb
FROM MaxLevel
ORDER BY RowNumbers

答案 1 :(得分:2)

另一种方式......

create table #vdata
(
cola varchar(10),
colb varchar(10)
 );

insert into #vdata values('A','B'),('B','C'),('A','X'),('Z','L'),
('N','M'),('O','P'),('R','Z'),('X','Y'),('T','N'),('F','E'),('G','H');



with src as
(
    select row_number() over(order by cola, colb) id, cola, colb
    from #vdata
)
, [matched] as
(
    select s1.*
    , (select min(s2.id) from src s2 where (s1.cola = s2.cola or s1.colb = s2.cola or s1.cola = s2.colb or s1.colb = s2.colb)) id2
    from src s1
)
, [result] as
(
    select m1.*
    , (select m2.id2 from [matched] m2 where m2.id = m1.id2) [id3]
    from [matched] m1
)
select cola, colb, dense_rank() over(order by id3) [rank]
from [result]
order by id