oraclesql中的谓词优先级

oraclesql中的谓词优先级,sql,oracle,Sql,Oracle,我有一个查询,其中我只需要根据谓词首选项的降序从表中返回一行。例如: SELECT * FROM Tbl WHERE col = 1 OR col = 2 OR col = 3; 在上面的场景中,如果col=1,我不想返回col=2或3的数据,只返回col=1的数据 如果col!=但是col=2或3,我只想返回col=2的数据,以此类推 有没有一个简单的方法来实现这一点?如果我解释的方式令人困惑,请提前道歉 编辑 为消除混淆,请参阅以下示例数据: With t

我有一个查询,其中我只需要根据谓词首选项的降序从表中返回一行。例如:

SELECT  *
FROM    Tbl
WHERE   col = 1
OR      col = 2 
OR      col = 3;
在上面的场景中,如果col=1,我不想返回col=2或3的数据,只返回col=1的数据

如果col!=但是col=2或3,我只想返回col=2的数据,以此类推

有没有一个简单的方法来实现这一点?如果我解释的方式令人困惑,请提前道歉

编辑

为消除混淆,请参阅以下示例数据:

With tbl As (
Select  1 As RECORD_ID, 'This is the string I want to return' str,                            'FIRST'  priority   From dual Union All
Select  1,              'This is the string i want to return, if CONDITION1 does not exist',  'SECOND'            From dual Union All
Select  1,              'this is the string i will return if i find no others',               'DEFAULT'           From dual Union All
Select  2,              'This is the string i want to return, if CONDITION1 does not exist',  'SECOND'            From dual Union All
Select  2,              'this is the string i will return if i find no others',               'DEFAULT'           From dual
)
Select  RECORD_ID,
        str
From    tbl
Where   xxx;
所以在上面的例子中,如果我查询记录\ ID 1,我希望返回第一个字符串,如果我查询记录\ ID 2,我应该得到第二个字符串

此时,所有三个字符串都将返回。

您可以尝试:

SELECT  t1.*
FROM    Tbl t1
WHERE   t1.col in (1,2,3)
ORDER BY t1.col
FETCH FIRST 1 ROWS ONLY;

一种方法使用排序:

select t.*
from (select t.*
      from t
      where col in (1, 2, 3)
      order by (case col when 1 then 1 when 2 then 2 when 3 then 3 end)
     ) t
where rownum = 1;

显然,在您的情况下,
orderby
可以是
orderby col
,但一般情况是使用
case

一种标准且常用的方法是使用
行号()。Oracle
ROWNUM
不可移植:

WITH data AS (
    SELECT t.*, ROW_NUMBER() OVER (ORDER BY LENGTH(priority)) AS rn
    FROM Tbl t WHERE col in (1, 2, 3)
)
SELECT * FROM data WHERE rn = 1;
这里还有一些基本相同的变体,它们使用
min()
编辑:随着需求的更新,这些调整可以获得正确的顺序,但原则上它们仍然可以工作

SELECT * FROM Tbl
WHERE col = (SELECT MIN(col) FROM Tbl);
更像第一个:

WITH data AS (
    SELECT t.*, MIN(col) OVER () AS mn
    FROM Tbl t WHERE col in (1, 2, 3)
)
SELECT * FROM data WHERE col = mn;

您可能希望查看查询计划,以确定哪一个最适合您,尽管我怀疑您的表只有几行。

根据每个谓词的选择性,您可以通过将查询分离为单独的组件来获得好处,例如

SQL> select * from
  2  ( select x
  3    from   t1
  4    where  x = :b1   -- first condition
  5    union all
  6    select x
  7    from   t1
  8    where  y = :b1   -- second condition
  9  )
 10  where rownum = 1
 11  /
如果联合中的第一个查询全部找到一行,那么我们可以完全避免第二个查询

您可以在这里找到一个证明“短路”处理的工作示例


是否必须设置
col
?必须处理空值会使事情复杂化。编辑:@Prateek,对,我误解了…@Ben373他的意思是根据条件匹配返回结果。Rownum将返回第一行right?如果它等于2,则肯定
col
不能等于1。您可能需要添加一些示例数据和预期结果。@mustaccio它跨多行数据。对象将根据可用的配置返回不同的字符串,并带有返回行的首选项。e、 g.如果我有一行col=1,我应该返回它,忽略col=2或col=3的结果,即使这些记录存在。实际上,我想在第一个条件下比赛,但如果没有比赛,就在第二个条件下比赛,以此类推。我希望这有助于澄清问题。“首先”是什么顺序?您的查询中没有。您好Gordon,在您的case表达式中不需要
end
(case col当1时,1当2时,2当3时,3当3结束)
对不起,我应该澄清,使用整数只是示例。我已经更新了我的问题。是否可以按此顺序指定不同的谓词?@mmartin2409是的,您可以使用另一个排序表达式。巧合的是,
length()
将为您提供正确的排序。漫长的道路只是一个明确的
case
表达式:
case优先级在'first'时为1,在'second'时为1,然后是2,否则3结束