1

我正在处理以下形式的表格:

  A        B
  ------   -----------
   1       value1
   2       value2
   3       value3
  -1       value4

在此表中-1,如果列中没有其他匹配项,则该值表示全部捕获A。这意味着,查询A = 2应该返回一条记录,其value2值为 B 列的值。如果查询表,比如说 ,A = 6那么 B 的值应该是value4(因为它是与全部捕获关联的值)。

实现这一目标的“最佳”查询是什么?有更好的解决方案吗?如果有帮助,我在SQLFiddle编写了一个小型设置示例。

数据库是 SQL Server。

你能帮我吗?非常感谢。

4

5 回答 5

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
于 2012-07-26T17:23:59.693 回答
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再次测试

于 2012-07-26T17:25:20.573 回答
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; 

应该管用。

尽管如此,这听起来像是一个糟糕的设计问题。我会查看需要这个的应用程序,看看是否没有更简洁的方法来实现默认值。

于 2012-07-26T17:28:32.823 回答
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”。


子句中的 CASE 表达式ORDER BY确保 -1 的“全部捕获”值是“最后的手段”,-1 将是列表中的最后一个值,任何其他任何值都将出现在排序中的 -1 之前.

 A  expr
--  ---- 
-2     0
-1     1 
 0     0
 1     0
 2     0

所以,当我ORDER BY expr保证 -1 的值将是列表中的最后一个时。结果集排序后,TOP 1将返回不超过 1 行。因此,只有在没有找到其他匹配值时才会返回与 -1 “catch all” 值关联的值。

于 2012-07-26T18:10:21.470 回答
0
if exists(select * from YourTable WHERE A=6)
  select * from YourTable WHERE A=6
else
  select * from YourTable WHERE A<0
于 2012-07-26T17:25:25.053 回答