Table 过滤每行第一个匹配项的值参数
Table Valued Parameter to filter first match for each row
我有一个 table 看起来像这样:
id1 | id2 | value | id3
1 | abc | 23 | apt-1
1 | abc | 24 | apt-2
2 | def | 25 | apt-3
3 | def | 25 | apt-3
我需要从上面的 table 中获取匹配 table 值参数的第一行,如下所示:
id1 | id2 |
1 | abc |
2 | def |
我想要的结果是
id1 | id2 | value | id3
1 | abc | 23 | apt-1
2 | def | 25 | apt-3
相反,我在 table 中返回了三行。
id1 | id2 | value | id3
1 | abc | 23 | apt-1
1 | abc | 24 | apt-2
2 | def | 25 | apt-3
我该如何解决这个问题?这样做的效率如何?这是一个临时解决方案,适用于我们写入的数据多于当前读取的数据,但将来也会基于 id3 进行读取。
让我们调用 table Foo 和 tvp tvpInput。
我尝试了以下两个查询:
--Approach 1
SELECT *
FROM Foo as ret
INNER JOIN @tvpInput t
ON
t.id1 = ret.id1
AND t.id2 = ret.id2
--Approach 2
SELECT *
FROM Foo AS ret
WHERE EXISTS
(
SELECT t.id1, t.id2 FROM @tvpInput t
WHERE
ret.id1 = t.id1
AND ret.id2 = t.id2
)
如果您只需要一行,可以使用 TOP。请记住,在 SQL 表中没有隐含的排序,因此您需要指定 ORDER BY 来接收确定的结果,例如
SELECT TOP 1 f.*
FROM Foo f
INNER JOIN @tvpInput t
ON t.id1 = ret.id1 AND t.id2 = ret.id2
ORDER BY f.id3
这是您可以执行此操作的一种方法。还有其他几种方法也可以。
select *
from
(
SELECT *, ROW_NUMBER() over(partition by ret.id1, ret.id2 order by (select newid())) as RowNum
FROM Foo as ret
INNER JOIN @tvpInput t ON t.id1 = ret.id1
AND t.id2 = ret.id2
) x
where x.RowNum = 1
我有一个 table 看起来像这样:
id1 | id2 | value | id3
1 | abc | 23 | apt-1
1 | abc | 24 | apt-2
2 | def | 25 | apt-3
3 | def | 25 | apt-3
我需要从上面的 table 中获取匹配 table 值参数的第一行,如下所示:
id1 | id2 |
1 | abc |
2 | def |
我想要的结果是
id1 | id2 | value | id3
1 | abc | 23 | apt-1
2 | def | 25 | apt-3
相反,我在 table 中返回了三行。
id1 | id2 | value | id3
1 | abc | 23 | apt-1
1 | abc | 24 | apt-2
2 | def | 25 | apt-3
我该如何解决这个问题?这样做的效率如何?这是一个临时解决方案,适用于我们写入的数据多于当前读取的数据,但将来也会基于 id3 进行读取。
让我们调用 table Foo 和 tvp tvpInput。
我尝试了以下两个查询:
--Approach 1
SELECT *
FROM Foo as ret
INNER JOIN @tvpInput t
ON
t.id1 = ret.id1
AND t.id2 = ret.id2
--Approach 2
SELECT *
FROM Foo AS ret
WHERE EXISTS
(
SELECT t.id1, t.id2 FROM @tvpInput t
WHERE
ret.id1 = t.id1
AND ret.id2 = t.id2
)
如果您只需要一行,可以使用 TOP。请记住,在 SQL 表中没有隐含的排序,因此您需要指定 ORDER BY 来接收确定的结果,例如
SELECT TOP 1 f.*
FROM Foo f
INNER JOIN @tvpInput t
ON t.id1 = ret.id1 AND t.id2 = ret.id2
ORDER BY f.id3
这是您可以执行此操作的一种方法。还有其他几种方法也可以。
select *
from
(
SELECT *, ROW_NUMBER() over(partition by ret.id1, ret.id2 order by (select newid())) as RowNum
FROM Foo as ret
INNER JOIN @tvpInput t ON t.id1 = ret.id1
AND t.id2 = ret.id2
) x
where x.RowNum = 1