首页 > 解决方案 > 如何根据它们是否可用(非 Null)或不可用(Null)在 Oracle/SQL 中动态获取值年

问题描述

假设我有一张桌子,上面有一个人的体重。

 NAME     2012        2013       2014         2015        2016         2017      2018         2019
JOHN      180          185       192          205         199          198       193          null
MIKE      190          191       191          195         195          195       195          195

我想要做的是获取最后一个 NON NULL 年份的最小值/最大值。(如下图结果集)

NAME     MIN         MAX
JOHN     192         205
MIKE     195         195 

以下是我尝试过的,有没有更好的方法来做到这一点?

SELECT 
    CASE WHEN 2019 IS NULL
         AND 2018 > 2017 > 2016 > 2015 > 2014
         THEN 2018
         WHEN 2019 IS NULL
         AND 2017 > 2016 > 2015 > 2014 > 2018
         THEN 2017
         WHEN 2019 IS null
         AND 2016 > 2017 > 2018 > 2015 > 2014
         THEN 2016
         WHEN 2019 IS NULL
         AND 2015 > 2018 > 2017 > 2016 > 2014
         THEN 2015
         WHEN 2019 IS NULL
         AND 2014 > 2018 > 2017 > 2016 > 2015
         THEN 2014
         WHEN 2019 IS NOT NULL
         AND 2019 > 2018 > 2017 > 2016 > 2015 > 2014
         THEN 2019
         WHEN 2019 IS NOT NULL
         AND 2018 > 2017 > 2016 > 2015 > 2014 > 2018
         THEN 2018
         WHEN 2019 IS NOT null
         AND 2017 > 2017 > 2018 > 2015 > 2014 > 2019
         THEN 2017
         WHEN 2019 IS NOT NULL
         AND 2016> 2015 > 2018 > 2017 > 2019 > 2014
         THEN 2016
         WHEN 2019 IS NOT NULL
         AND 2015 > 2014 > 2018 > 2017 > 2016 > 2019
         THEN 2015
         WHEN 2019 IS NOT NULL
         AND 2014 > 2015 > 2015 > 2018 > 2017 > 2016 > 2019
         THEN 2014
          END                                  as MAX

提前致谢 从表 WHERE

标签: sqloracle

解决方案


您的表格设计不是最佳的,最好将其标准化,将每年的每个重量放在单独的记录上,而不是列上。话虽如此,如果您必须继续,您可以做的一个技巧是使用-1COALESCE替换列权重。NULL这将有效地将其从图片中删除。然后,使用标量GREATEST函数找到合法的最大值:

SELECT
    GREATEST(COALESCE("2019", -1),
             COALESCE("2018", -1),
             COALESCE("2017", -1),
             COALESCE("2016", -1),
             COALESCE("2015", -1),
             COALESCE("2014", -1),
             COALESCE("2013", -1),
             COALESCE("2012", -1)) AS max_weight
FROM yourTable;

注意:如果每一列都可能是NULL,那么上面的调用GREATEST将返回 -1。在这种情况下,您可以将该值保留为没有有效数据的市场,或者您可以包装在CASE表达式中并替换为其他值。


推荐阅读