从多个列中查找最大值,第二个最大值和最小值

时间:2019-09-13 09:46:49

标签: sql sql-server tsql

我有一个表,其中有列的长度,宽度,高度,我要查找,在三列中,最大将变为长度,第二个最大将变为宽度,最小将为高度。

table name dimension

length  width   height
5.60    3.70    0.90
13.50   6.54    3.50
14.33   7.95    3.86
6.42    6.69    7.95
12.00   10.00   9.00
5.60    3.70    3.70

我尝试了案例逻辑,发现能够找出max,min,但是第二个max并没有得到想要的结果。

select length = case
                    when dimension.[length] >= dimension.width and dimension.[length] >= dimension.height then dimension.[length]
                    when dimension.[width] >= dimension.[length] and dimension.[width] >= dimension.height then dimension.[width]
                    when dimension.[height] >= dimension.[length] and dimension.[height] >= dimension.width then dimension.[height]
                end,
        width = case 
                    when (dimension.[length] <= dimension.width and dimension.[length] >= dimension.height)  then dimension.[length] 
                    when (dimension.[width] <= dimension.[length] and dimension.[width] >= dimension.height) then dimension.[width]
                    when (dimension.[height] <= dimension.[length] and dimension.[height] >= dimension.width )then dimension.[height]
                end,
        height = case 
                    when dimension.[length] <= dimension.width and dimension.length<= dimension.height then dimension.[length]
                    when dimension.[width] <= dimension.[length] and dimension.[width] <= dimension.height then dimension.[width]
                    when dimension.[height] <= dimension.[length] and dimension.[height] <= dimension.width then dimension.[height]
                end

from dimension

返回长度,宽度和高度时,第二个最大值应该正确显示。

预期的输出

length  width   height
5.60    3.70    0.90
13.50   6.54    3.50
14.33   7.95    3.86
7.95    NULL    6.42
12.00   10.00   9.00
5.60    3.70    3.70

但是在某些情况下,我在宽度列中得到空值。

3 个答案:

答案 0 :(得分:0)

对于SQL Server 2012 +:

使用ORDER BYOFFSETFETCH来获得预期输出的另一种可能方法:

表格:

CREATE TABLE #Dimensions (
    [length] numeric(10, 2),  
    [width] numeric(10, 2),   
    [height] numeric(10, 2)
)
INSERT INTO #Dimensions
    ([length], [width], [height])
VALUES
    (5.60,    3.70,    0.90),
    (13.50,   6.54,    3.50),
    (14.33,   7.95,    3.86),
    (6.42,    6.69,    7.95),
    (12.00,   10.00,   9.00),
    (5.60,    3.70,    3.70)

声明:

SELECT c.*
FROM #Dimensions d
CROSS APPLY (
    SELECT 
        [length] = (SELECT N FROM (VALUES (d.[length]), (d.[width]), (d.[height])) v(N) ORDER BY N DESC OFFSET 0 ROWS FETCH NEXT 1 ROW ONLY),
        [width] = (SELECT N FROM (VALUES (d.[length]), (d.[width]), (d.[height])) v(N) ORDER BY N DESC OFFSET 1 ROWS FETCH NEXT 1 ROW ONLY),
        [height] = (SELECT N FROM (VALUES (d.[length]), (d.[width]), (d.[height])) v(N) ORDER BY N DESC OFFSET 2 ROWS FETCH NEXT 1 ROW ONLY)
) c

输出:

----------------------
length  width   height
----------------------
5.60    3.70    0.90
13.50   6.54    3.50
14.33   7.95    3.86
7.95    6.69    6.42
12.00   10.00   9.00
5.60    3.70    3.70

对于SQL Server 2008 +:

当不支持将ORDER BYOFFSET结合使用的FETCH时,使用ROW_NUMBER()的方法也是一种解决方案:

SELECT 
    [length] = c1.N,
    [width] = c2.N,
    [height] = c3.N
FROM #Dimensions d
CROSS APPLY (SELECT N, ROW_NUMBER() OVER (ORDER BY N DESC) AS RN FROM (VALUES (d.[length]), (d.[width]), (d.[height])) v(N)) c1
CROSS APPLY (SELECT N, ROW_NUMBER() OVER (ORDER BY N DESC) AS RN FROM (VALUES (d.[length]), (d.[width]), (d.[height])) v(N)) c2
CROSS APPLY (SELECT N, ROW_NUMBER() OVER (ORDER BY N DESC) AS RN FROM (VALUES (d.[length]), (d.[width]), (d.[height])) v(N)) c3
WHERE (c1.RN = 1) AND (c2.RN = 2) AND (c3.RN = 3)

答案 1 :(得分:0)

--------逻辑------------------------ 通过关键列将其垂直分组以应用聚合逻辑


select * from sample;

 length | width | height 

 6 |     4 |      1
14 |     7 |      4
---------------------------------
This query been tried in Postgres   (U can use rownum in oracle in place of grpno)

with basedata as  (select floor(random()*100) grpno,length,width ,height from sample)  
select max(measurmnt) as length,min(measurmnt) height,sum(measurmnt)-( max(measurmnt)+min(measurmnt)) as width from 
 ( select grpno,length measurmnt from basedata union all  
         select grpno,width from basedata  union all 
 select grpno,height from basedata order by 1
) as outerq
group by grpno;
 length | height | width 
--------+--------+-------
      6 |      1 |     4
     14 |      4 |     7

答案 2 :(得分:0)

希望这对您有用:

select
    length = (select max(v) from (values (length), (width), (height)) as t(v)),
    width = (select (sum(v) - max(v) - min(v)) from (values (length), (width), (height)) as t(v)),
    height = (select min(v) from (values (length), (width), (height)) as t(v))
from dimension
相关问题