1

假设我的表结构如下:

id | Word
---|-----
1  | a
2  | aa
.  | ..

我有一个这样的 id 列表:

(...,900, 1000, 2000, 3000, 4000,....)

我想在上面的列表中找到小于每个 id 的最大 id。我的表 id 不一定是连续的,两个连续的 id 之间存在一些差距,例如:

(...,889,900,950,952,997,1000,1001,1010,1920,2000,2990,3000,3500,4000,...)

根据上述列表的预期结果将是:

(889, 997, 1920, 2990, 3500,...)

我如何达到预期的效果?

4

3 回答 3

2

使用公用表表达式ROW_NUMBER()

;WITH cte AS(
    SELECT *, ROW_NUMBER() OVER (ORDER BY ID) rowNum
    FROM example)

SELECT ID, word
FROM cte
WHERE rowNum IN (
    SELECT (rowNum - 1)
    FROM cte
    WHERE ID IN ('900','1000','2000','3000','4000'))
    --WHERE ID IN (SELECT ID FROM <tableWithIDs>))

在此处输入图像描述


如果您已经ID在另一个表中找到了所有要查找的内容,则可以改用我的答案的注释部分而不是硬编码IN列表。

这仅在ID您要查找的表中存在时才有效。因此,如以下评论中所述,如果您正在搜索,则1001不会得到997,除非1001表中存在(意思是,如果存在,它将获得一个rowNum值并可以用于在子查询中递减)

[在这里演示]


以下是另一种查看ID每行前一个内容的方法:

SELECT *, LEAD(ID,1) OVER(ORDER BY ID DESC) PreviousID
FROM example
ORDER BY ID

在此处输入图像描述

于 2018-03-11T06:02:50.540 回答
1

我会简单地做:

select v.val, t.*
from (values (900), (1000), (2000), (3000), (4000) ) v(val) outer apply
     (select top 1 t.*
      from t
      where t.id < v.val
      order by t.id desc
     ) t;

这使您可以查看每一行的值。这可能很重要,因为 SQL 结果集是无序的,并且哪个值与哪个行对应并不明显。

编辑:

如果您知道表中的行号,那么性能最高的解决方案可能是:

select t.*
from (select t.*, lead(id) over (order by id) as next_id
      from t
     ) t
where next_id in ( . . . );
于 2018-03-11T11:14:36.450 回答
0

这应该有效,我认为它会相当有效。

declare @V table (num int primary key);
insert into @V values (800), (889), (900), (997), (1000), (1910), (1920), (2000), (2990), (3000), (3500), (4000);
declare @T table (num int primary key);
insert into @T values (800), (900), (1000), (1200), (2000), (3000), (4000);
select tt.vP 
  from ( select t.num as t, v.num as v
              , LAG(v.num) over (order by v.num) as vP
           from @V v
           left join  @T t
             on v.num = t.num 
       ) tt 
 where tt.t  is not null 
   and tt.vP is not null
 order by tt.vP

不清楚你希望它如何表现

select t.num 
     , (select max(v.num) from @V v where v.num < t.num) as prior
from @T t
于 2018-03-11T13:24:19.957 回答