我有一个查询,我需要根据谓词首选项的降序从表中返回一行。例如:
SELECT *
FROM Tbl
WHERE col = 1
OR col = 2
OR col = 3;
在上面的场景中,如果col = 1,我不想返回col = 2或3的数据,只有col = 1的数据。
如果col!= 1但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;
所以在上面的例子中,如果我查询了RECORD_ID 1,我希望返回FIRST字符串,如果我查询了RECORD_ID 2,我应该得到SECOND。
此刻,所有三个字符串都将返回。
答案 0 :(得分:1)
一种方法使用排序:
care_team_member_name care_team_member_Engagement_id care_team_member_start_date care_team_member_end_date
TM-000022181 a1Y0q0000000woaEAA 2017-08-16 NULL
TM-000022182 a1Y0q0000000wobEAA 2017-08-16 NULL
TM-000022183 a1Y0q0000000wocEAA 2017-08-16 NULL
TM-000022184 a1Y0q0000000wodEAA 2017-08-16 NULL
TM-000022185 a1Y0q0000000woeEAA 2017-08-16 NULL
TM-000030523 a1Y0q0000000woVEAQ 2018-01-03 2018-02-28
TM-000031508 a1Y0q0000000woVEAQ 2018-01-25 2018-02-28
TM-000031798 a1Y0q0000000woVEAQ 2018-03-01 2018-03-05
TM-000031802 a1Y0q0000000woVEAQ 2018-03-01 2018-03-05
TM-000031803 a1Y0q0000000woVEAQ 2018-03-01 2018-03-05
TM-000031805 a1Y0q0000000woVEAQ 2018-03-01 2018-03-05
TM-000031806 a1Y0q0000000woVEAQ 2018-03-01 2018-03-05
TM-000023500 a1Y0q0000000woVEAQ 2017-09-21 2018-03-05
TM-000023503 a1Y0q0000000woVEAQ 2017-09-22 2018-03-05
显然,在您的情况下,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;
可能是order by
,但一般情况是使用order by col
。
答案 1 :(得分:0)
你可以尝试:
SELECT t1.*
FROM Tbl t1
WHERE t1.col in (1,2,3)
ORDER BY t1.col
FETCH FIRST 1 ROWS ONLY;
答案 2 :(得分:0)
执行此操作的标准和常见方法是使用ROW_NUMBER()
。 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;
您可能希望查看查询计划以确定哪一个最适合您,尽管我怀疑您的表只有几行。
答案 3 :(得分:0)
根据每个谓词的选择性,您可以通过将查询分成单个组件来获益,即
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 /
如果UNION ALL中的第一个查询找到一行,那么我们可以完全避免第二个查询。
你可以在这里找到一个证明“短路”处理的工作实例
https://connor-mcdonald.com/2016/03/14/the-first-matching-row/