我有一个 5 字段的表,我想做一个这样的 qry:
SELECT *
FROM dbo.table
WHERE somefield in (90,120,30,90)
问题是我在表的行中有几个 90、120 和 30 值,但我只想返回符合条件的前 4 行。
有没有什么简单的方法可以做到这一点?我使用的是 SQL Server 2008。
CREATE TABLE ForgeRock
([id] int, [somefield] int)
;
INSERT INTO ForgeRock
([id], [somefield])
VALUES
(1, 90),
(2, 90),
(3, 120),
(4, 30),
(5, 30),
(6, 90),
(7, 10),
(8, 20),
(9, 90),
(10, 30),
(11, 20)
;
Fidle with data and query。
预期结果将是 90,120,20,90
及其受尊重的 id
。
答案 0 :(得分:0)
您按列表过滤,in
只检查每个输入值的成员资格。因此,列表中值的顺序位置无关紧要,它仅用于过滤。要区分相同值的两个不同实例,您需要将此列表转换为表格或进行其他一些保存订单信息的转换。
一种方式可以是table value constructor:
with flt as (
select
val,
row_number() over(partition by val order by val) as rn /*To distinguish instances of the value*/
from(values (90),(120),(30),(90)) as t(val)
)
, base as (
select
f.*,
row_number() over(partition by somefield order by id) as rn
from ForgeRock as f
where somefield in (select flt.val from flt) /*To restrict input before row number*/
)
select b.*
from base as b
join flt
/*Match value AND repetition*/
on b.somefield = flt.val
and b.rn = flt.rn
<块引用>
id | somefield | rn |
---|---|---|
4 | 30 | 1 |
1 | 90 | 1 |
2 | 90 | 2 |
3 | 120 | 1 |
对于现代版本,如果您从外部收到此列表,也有 openjson 的可能性:
with flt as (
select
[value] as val,
row_number() over(partition by [value] order by [key]) as rn /*To distinguish instances of the value*/
from openjson('[90, 120, 30, 90]') as t
)
...
the same code