我正在尝试编写一个从列表中返回项目的sql脚本,如果该项目可以在列表中找到,如果没有,则返回添加到列表中的最新项目。我想出了一个使用count和if-else语句的解决方案。但是我的表有非常频繁的I / O操作,我认为这个解决方案效率很低。有没有人可以优化此解决方案或更好的方法。
这是我的解决方案:
DECLARE @result_set INT
SET @result_set = (
SELECT COUNT(*) FROM
( SELECT *
FROM notification p
WHERE p.code = @code
AND p.reference = @reference
AND p.response ='00'
) x
)
IF(@result_set > 0)
BEGIN
SELECT *
FROM notification p
WHERE p.code = @code
AND p.reference = @reference
AND p.response ='00'
END
ELSE
BEGIN
SELECT
TOP 1 p.*
FROM notification p (nolock)
WHERE p.code = @code
AND p.reference = @reference
ORDER BY p.id DESC
END
我也认为应该有一种方法来重复这个select语句:
SELECT *
FROM notification p
WHERE p.code = @code
AND p.reference = @reference
AND p.response ='00'
我只是不够精通SQL来弄明白。
你可以这样做:
SELECT TOP (1) n.*
FROM notification n
WHERE p.code = @code AND p.reference = @reference
ORDER BY (CASE WHEN p.response ='00' THEN 1 ELSE 2 END), id DESC;
这将首先返回'00'
响应的行,然后返回任何其他行。我希望ORDER BY
的另一个列能够处理新近度,但是您的示例代码并没有提供任何关于这可能是什么的线索。
WITH ItemIWant AS (
SELECT *
FROM notification p
WHERE p.code = @code
AND p.reference = @reference
AND p.response ='00'
),
SELECT *
FROM ItemIWant
UNION ALL
SELECT TOP 1 *
FROM notification p
WHERE p.code = @code
AND p.reference = @reference
AND NOT EXISTS (SELECT * FROM ItemIWant)
ORDER BY id desc
这将通过桌面上的最小传递来实现。如果ItemIWant没有返回任何行,它将只返回顶行。没有条件逻辑,因此可以有效地编译和索引。