我需要在sql表中显示三列的中间值。
例如:对于数据
col1 col2 col3
759 736 773
然后输出应为759
。
最好的方法是什么?
答案 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 提供的新条件:
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