其中条件复杂的逻辑

时间:2017-06-30 12:59:43

标签: sql oracle select

我有一张看起来像这样的桌子......

ID ColumnA ColumnB ColumnC
1 ALL ALL ALL 2 A ALL ALL
3 A A B全部4 A B C

这里“ALL”只是一个默认值。

所以在SELECT语句中如果我的条件是ColumnA ='D'而ColumnB ='D'而ColumnC ='D'那么它应该返回第一行(ID = 1)

如果条件为ColumnA ='A'且ColumnB ='B'且ColumnC ='D'则应返回第三行(ID = 3)

如何在不多次阅读表的情况下实现此目的?

4 个答案:

答案 0 :(得分:0)

在select语句中添加一列:

  100*CASE WHEN ColA=VALUE1 THEN 2 WHEN ColA='ALL' THEN 1 ELSE 0 END
   + 10*CASE WHEN ColB=VALUE2 THEN 2 WHEN ColB='ALL' THEN 1 ELSE 0 END
   + 1*CASE WHEN ColC=VALUE3 THEN 2 WHEN ColC='ALL' THEN 1 ELSE 0 END AS SortOrder

然后通过DESC订购并选择排序前1行,其中SortOrder> 0

我来自MSSQL所以oracle-syntax可能会有所不同,但原则应该有效。

答案 1 :(得分:0)

我想这很有效,至少在SQL-Server中没有(没有oracle):

SELECT TOP 1 ID, ColumnA, ColumnB, ColumnC FROM
(
    SELECT ID, ColumnA, ColumnB, ColumnC,
           CASE WHEN (ColumnA=@col1 AND ColumnB=@col2 AND ColumnC=@col3) THEN 1 ELSE 0 END As BestMatch,
           CASE WHEN (ColumnA=@col1 AND ColumnB=@col2 AND ColumnC='ALL') THEN 1 ELSE 0 END As SecondBestMatch,
           CASE WHEN (ColumnA=@col1 AND ColumnB='ALL' AND ColumnC='ALL') THEN 1 ELSE 0 END As ThirdBestMatch
    FROM dbo.Table_Name
) x
ORDER BY BestMatch DESC, SecondBestMatch DESC, ThirdBestMatch DESC, ID ASC

我认为在oracle中你需要用TOP 1

替换where rownum = 1

答案 2 :(得分:0)

选择符合条件的所有行。然后对它们进行排名并保持最佳排。如果出现平局,我们会任意挑选一条最好的行。

从Oracle 12c开始:

select id, columna, columnb, columnc
from mytable
where columna in ('A', 'ALL')
  and columnb in ('B', 'ALL')
  and columnc in ('D', 'ALL')
order by 
  case when columna = 'A' then 1 else 0 end +
  case when columnb = 'B' then 1 else 0 end +
  case when columnc = 'D' then 1 else 0 end desc
fetch first 1 row only;

在早期版本中:

select id, columna, columnb, columnc
from
(
  select
    id, columna, columnb, columnc,
    row_number() over (order by 
      case when columna = 'A' then 1 else 0 end +
      case when columnb = 'B' then 1 else 0 end +
      case when columnc = 'D' then 1 else 0 end desc) as rn
  from mytable
  where columna in ('A', 'ALL')
    and columnb in ('B', 'ALL')
    and columnc in ('D', 'ALL')
) where rn = 1;

答案 3 :(得分:-1)

这不能得到你想要的吗?

(ColumnA='D' or ColumnnA='ALL') 
 and (ColumnB='D' or ColumnB='ALL')
 and (ColumnC='D' or ColumnC='ALL')

(编辑)

要获得“最佳匹配”,可能会有多个,然后按如下方式应用订单并选择第一行。

order by
    case when ColumnA='ALL' then 0 else 1 end
      + case when ColumnB='ALL' then 0 else 1 end
      + case when ColumnB='ALL' then 0 else 1 end DESC