SQL在重复行中获得最接近的两行

时间:2017-11-04 05:27:12

标签: sql sql-server

我有下表

ID   Name      Stage
1    A           1      
1    B           2                 
1    C           3  
1    A           4
1    N           5
1    B           6
1    J           7 
1    C           8
1    D           9
1    E           10      

我需要输出如下,参数A and N需要选择最接近的行,其中舞台之间的差异最小

   ID   Name      Stage
    1    A           4      
    1    N           5   

我需要选择舞台之间差异最小的行

2 个答案:

答案 0 :(得分:1)

如果您知道最小差异始终为1

,则此解决方案有效
    SELECT * 
    FROM myTable as a
    CROSS JOIN myTable as b
    where a.stage-b.stage=1;


     a.ID   a.Name      a.Stage  b.ID   b.Name      b.Stage
        1    A           4        1       N             5

如果您不了解最低

,则更简单
SELECT *
FROM myTable as a
    CROSS JOIN myTable as b
where a.stage-b.stage in (SELECT min (a.stage-b.stage) 
    FROM myTable as a
    CROSS JOIN myTable as b)

答案 1 :(得分:1)

此查询可以有效地使用(name, stage)上的索引:

WITH cte AS (
   SELECT TOP 1
          a.id AS a_id, a.name AS a_name, a.stage AS a_stage
        , n.id AS n_id, n.name AS n_name, n.stage AS n_stage
   FROM   tbl a
   CROSS  APPLY  (
      SELECT TOP 1 *, stage - a.stage AS diff
      FROM   tbl  
      WHERE  name = 'N'
      AND    stage >= a.stage
      ORDER  BY stage

      UNION ALL
      SELECT TOP 1 *, a.stage - stage AS diff
      FROM   tbl  
      WHERE  name = 'N'
      AND    stage < a.stage
      ORDER  BY stage DESC
      ) n
   WHERE  a.name = 'A'
   ORDER  BY diff
   )
SELECT a_id AS id, a_name AS name, a_stage AS stage FROM cte
UNION ALL
SELECT n_id, n_name, n_stage FROM cte;

SQL Server使用CROSS APPLY代替标准SQL LATERAL

如果是关系(等差),获胜者是任意的,除非你添加更多ORDER BY个表达作为决胜局。

dbfiddle here