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
一种标准且常用的方法是使用行号()。OracleROWNUM
不可移植:
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结束