我正在处理以下表格的表格:
A B
------ -----------
1 value1
2 value2
3 value3
-1 value4
在此表中,如果列中的-1
没有其他匹配项,则值A
表示全部捕获。这意味着,对A = 2
的查询应该返回单个记录,其中value2
是列B的值。如果要查询该表,比如说A = 6
,那么值为B应该是value4
(因为它是与catch all相关的值)。
实现这一目标的“最佳”查询是什么?有更好的解决方案吗?我在SQLFiddle中编写了一个小型设置示例,如果有帮助的话。
数据库是SQL Server。
你能帮忙吗?非常感谢。答案 0 :(得分:2)
select top (1) A, B
from (
select A, B, 0 as priority from t where A = @value
union
select A, B, 1 from t where A = -1
) foo
order by priority
答案 1 :(得分:2)
DECLARE @param int
SET @param = 6
SELECT *
FROM test
WHERE a = @param OR (
a = -1 AND @param NOT IN (SELECT a FROM test)
)
将@param = 6
替换为@param = 2
再次测试
答案 2 :(得分:1)
在MySQL中,这将是微不足道的:
SELECT b FROM test WHERE a = @var or a = -1 ORDER BY a DESC LIMIT 1;
但是,MSSQL内置了这样的技巧 - 您需要添加一个存储过程来正确限制它。
修改强> 似乎在2005年,他们增加了一些分页功能:
SELECT TOP 1 b FROM test WHERE a = @var or a = -1 ORDER BY a DESC;
应该有用。
所有这一切,这听起来像是设计不佳的问题;我会查看需要它的应用程序,看看是否有更简洁的方法来实现默认值。
答案 3 :(得分:1)
以下是我编写查询的方法:
SELECT TOP 1 B
FROM mytable
WHERE A IN (2,-1)
ORDER BY CASE WHEN A = -1 THEN 1 ELSE 0 END, B;
此语句的硬编码搜索参数为“2”(如您的示例所示)。
显然,你会用你的搜索参数代替硬编码的“2”。
ORDER BY
子句中的CASE表达式确保-1的“catch all”值是“最后的手段”,-1将是列表中的最后一个值,任何其他任何值都将来到排序中的-1之前。
A expr
-- ----
-2 0
-1 1
0 0
1 0
2 0
因此,当我ORDER BY expr
时,我们可以保证在列表中最后一个值为-1。对结果集进行排序后,TOP 1
将返回不超过1行。因此,只有在找不到其他匹配值时,才会返回与-1“catch all”值关联的值。
答案 4 :(得分:0)
if exists(select * from YourTable WHERE A=6)
select * from YourTable WHERE A=6
else
select * from YourTable WHERE A<0