SQL - 返回大多数列匹配的行

时间:2015-04-03 17:59:27

标签: sql oracle

考虑下表:

Name   Color1    Color2    Color3   Prize
-----------------------------------------
Bob    Red       Blue      Green    Stapler
Bob    Red       Blue      NA       Pencil
Bob    Red       NA        NA       Lamp
Bob    Red       NA        NA       Chair
Bob    NA        NA        NA       Mouse Pad
鲍勃有3种颜色。这就是我想要的:

(#1) If Bob has Red, Blue, Green (match 3) ....  Return Stapler
(#2) If Bob has Red, Blue, Purple (match 2) ...  Return Pencil
(#3) If Bob has Red, Orange, Purple (match 1) .  Return Lamp AND Chair rows
(#4) If Bob has Brown, Pink, Black (match 0) ..  Return Mouse Pad

颜色只会出现在自己的列中。因此,在上面的示例中,Red仅位于Color1列中,而不会位于Color2或Color3中。黑色只能在Color3中,而不会在Color1或Color2中。等...

我只想要匹配最多的行。

我真的不想用4个单独的SELECT语句来执行此操作,并且每次检查它们是否返回一行。这就是我在存储过程中执行的操作,它很笨重。

如何在1个SQL语句中执行此操作?如果重要的话使用Oracle ......

感谢!!!

2 个答案:

答案 0 :(得分:1)

您可以使用case计算匹配数,然后获取最多的行。在Oracle中,这使用了一些子查询:

select name
from (select t.*
      from (select t.*,
                   ((case when color1 in ('Red', 'Blue', 'Green') then 1 else 0 end) +
                    (case when color2 in ('Red', 'Blue', 'Green') then 1 else 0 end) +
                    (case when color3 in ('Red', 'Blue', 'Green') then 1 else 0 end) +
                   ) as numMatches
            from table t
           ) t
      order by nummatches desc
     ) t
where rownum = 1;

答案 1 :(得分:1)

  

我只想要匹配最多的行。

您可以使用函数rank():

SQLFiddle

select name, color1, color2, color3, prize 
  from (
    select t.*, rank() over (order by decode(color1, 'Red', 1, 0) 
        + decode(color2, 'Blue', 1, 0) + decode(color3, 'Green', 1, 0) desc) rnk
      from t)
  where rnk = 1

返回大多数匹配的行。