【问题标题】:SQL Server 2008 R2: ROW_NUMBER()SQL Server 2008 R2:ROW_NUMBER()
【发布时间】:2014-11-04 20:51:17
【问题描述】:

我有以下数据:

示例

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 中的数据 OR 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    

上述结果的解释:第一行在开始时有行号1,然后再次分配给接下来的两条记录,因为column(cola or colb)中的任何一个都有值A or B所以。给第四条记录的行号2,因为它没有任何值A or B,并且以相同的方式继续处理。请注意,记录 7 的行号为 X and Y,其行号为 1,因为它与表中记录 2 处的 A 相关,即 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

【问题讨论】:

  • 如果 colb 中必须有可乐,那你怎么会在预期输出中得到“A”
  • @Pradeep,请再次阅读注意事项。
  • 现在我明白了..

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


【解决方案1】:

您需要表格中的某种 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

【讨论】:

    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-20
      • 2013-02-07
      • 2011-06-19
      • 2012-10-05
      • 1970-01-01
      相关资源
      最近更新 更多