表值参数用于过滤每行的第一个匹配项

时间:2015-11-05 20:13:51

标签: sql-server table-valued-parameters

我有一个看起来像这样的表:

id1 | id2 | value | id3
1   | abc | 23    | apt-1
1   | abc | 24    | apt-2
2   | def | 25    | apt-3
3   | def | 25    | apt-3

我需要从上表中获得与表值参数匹配的第一行,如下所示:

id1 | id2 |
1   | abc |
2   | def |

我希望结果是

id1 | id2 | value | id3
1   | abc | 23    | apt-1
2   | def | 25    | apt-3

相反,我在表格中取回了三行。

id1 | id2 | value | id3
1   | abc | 23    | apt-1
1   | abc | 24    | apt-2
2   | def | 25    | apt-3

我该如何解决这个问题?这会有什么效率?这是一个临时解决方案,用于我们编写的数据比当前正在读取的数据多,但将来也会基于id3进行读取。

让我们调用表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     
)

2 个答案:

答案 0 :(得分:0)

如果您只需要一行,则可以使用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

答案 1 :(得分:0)

这是你可以做到这一点的一种方法。还有其他几种方法也可以。

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