假设我的表结构如下:
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,...)
我如何取得理想的效果?
答案 0 :(得分:2)
使用common table expression和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
1}}值,可用于在子查询中递减)
以下是另一种查看每行ID
的内容的方法:
SELECT *, LEAD(ID,1) OVER(ORDER BY ID DESC) PreviousID
FROM example
ORDER BY ID
答案 1 :(得分:1)
我会这样做:
select t.*
from (select t.*, lead(id) over (order by id) as next_id
from t
) t
where next_id in ( . . . );
这允许您查看每行的值。这可能很重要,因为SQL结果集是无序的,并且哪个值与哪一行不一样。
编辑:
如果您知道行号在表中,那么最佳性能解决方案可能是:
# Gemfile
...
gem 'rspec-collection_matchers', group: :test
...
# spec/spec_helper.rb
...
require 'rspec/collection_matchers'
....
答案 2 :(得分: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