比较SQL表中的三列以获得中间值

时间:2015-04-27 16:51:42

标签: sql

我需要在sql表中显示三列的中间值。

例如:对于数据

col1    col2    col3
759     736     773

然后输出应为759

最好的方法是什么?

4 个答案:

答案 0 :(得分:5)

对于Oracle,MySql和Postgres:

select col1 + col2 + col3 - greatest(col1, col2, col3) - least(col1, col2, col3)

答案 1 :(得分:3)

您可以使用case表达式(不涵盖col [n]可以相等的情况 - 说明不清楚):

select case 
       when (col1 > col2 and col2 > col3) or (col3 > col2 and col2 > col1) then col2 
       when (col1 > col3 and col3 > col2) or (col2 > col3 and col3 > col1) then col3 
       when (col3 > col1 and col1 > col2) or (col2 > col1 and col1 > col3) then col1 
       end
from tbl

修改

考虑 OP 提供的新条件:

  1. 任何两列或全部三列值可以相等。
  2. 任何两列或全部三列都可以为空。你能告诉我如何处理这些案件。
  3. select case 
           when col2 is not null and
                ((col1 is null and col3 is null) or 
                 (col3 is null and col1 >= col2) or 
                 (col1 is null and col3 >= col2) or 
                 (col1 > col2 and col2 >= col3) or 
                 (col3 > col2 and col2 >= col1)) then col2 
           when col3 is not null and 
                ((col1 is null and col2 is null) or
                 (col2 is null and col1 >= col3) or 
                 (col1 is null and col2 >= col3) or 
                 (col1 > col3 and col3 >= col2) or 
                 (col2 > col3 and col3 >= col1)) then col3 
           when col1 is not null and 
                ((col2 is null and col3 is null) or
                 (col2 is null and col3 >= col1) or 
                 (col3 is null and col2 >= col1) or 
                 (col3 > col1 and col1 >= col2) or 
                 (col2 > col1 and col1 >= col3)) then col1 
           else 0
           end
    from tbl
    

答案 2 :(得分:0)

如果您正在使用Postgres,根据性能需求,解决此类问题的一种非常好的方法是使用语言扩展。我熟悉Python,这是一种比纯SQL更好的表达这种计算的语言,所以我可能会这样做(确保安装了ely=# create or replace function getmid (a integer, b integer, c integer) returns integer as $$ if (a is None) or (b is None) or (c is None): return None return sorted([a, b, c])[1] $$ LANGUAGE plpythonu; CREATE FUNCTION 语言扩展后):< / p>

ely=# select getmid(a.actor_id, b.movie_id, 3) 
      from actors a 
      join movies_actors b 
      on a.actor_id = b.actor_id
      limit 15;

我没有任何好的玩具数据来显示来自同一张桌子的三个整数列的计算,但是使用一些玩具表,你可以看到正在使用的功能:

 getmid 
--------
      3
      3
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
(15 rows)

输出

key

其中一个巨大的好处是你可以编写Python函数来概括列的数量,而将其作为存储过程编写则会更加痛苦并且手动扩展大量的case语句作为列数成长是非常不切实际的。

SQL的其他方言中可能存在类似的功能 - 我只能证明它如何与Postgres一起使用。

答案 3 :(得分:0)

这是SQL Server的一个工作示例。同样的想法将适用于其他平台。 (假设值为非空。)

declare @a int = 10;
declare @b int = 214;
declare @c int = 131;

select @a + @b + @c
  - (((@a + @b - abs(@a-@b)) / 2.0) + @c - abs(((@a + @b - abs(@a-@b)) / 2.0) - @c)) / 2.0
  - (((@a + @b + abs(@a-@b)) / 2.0) + @c + abs(((@a + @b + abs(@a-@b)) / 2.0) - @c)) / 2.0