从与 where in 列表中的所有项目匹配的表行中选择

时间:2021-07-02 13:59:35

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

我有一个 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

1 个答案:

答案 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
相关问题