简体   繁体   English

如何从多列获取最小/最小值但使用mysql忽略0作为最小值/最小值?

[英]How to get least/min value from multiple columns but ignore 0 as min/least value using mysql?

I am trying to fetch the result from 16 columns to find which column has the minimum value but that minimum value shouldn't be 0. 我试图从16列中获取结果,以查找哪个列具有最小值但该最小值不应为0。

so I have tried my query something like below based on some suggestions but it doesn't work for me as it returns 0. 所以我根据一些建议尝试了我的查询,但它对我不起作用,因为它返回0。

SELECT least(
    IFNULL(col_1,0),
    IFNULL(col_2,0),
    IFNULL(col_3,0),
    IFNULL(col_4,0),
    IFNULL(col_5,0),
    IFNULL(col_6,0),
    IFNULL(col_7,0),
    IFNULL(col_8,0),
    IFNULL(col_9,0),
    IFNULL(col_10,0),
    IFNULL(col_11,0),
    IFNULL(col_12,0),
    IFNULL(col_13,0),
    IFNULL(col_14,0),
    IFNULL(col_15,0),
    IFNULL(col_16,0)) as lowest
FROM `my_date_table` 
where date_id = '108'

Thanks and please don't mark as repeat question as I already go through some of the stack questions but couldn't find the right solution that I can apply on my query on php/mysql. 谢谢,请不要标记为重复问题,因为我已经完成了一些堆栈问题,但找不到我可以在php / mysql上查询的正确解决方案。

This is not an easy task. 这不是一件容易的事。 You cannot simply turn all 0 s to NULL s since LEAST() returns NULL if any of its arguments is NULL . 你不能简单地把所有的0秒至NULL小号因为LEAST()返回NULL ,如果它的任何参数是NULL

If you know in advance the maximum value accross all columns, you can use the trick commented by Barmar . 如果您事先知道所有列的最大值,则可以使用Barmar评论的技巧

Else, assuming that you have a primary key called id in the table, a (suboptimal) solution solution could be to unpivot the table using UNION ALL , while turning 0 values to NULL values; 另外,假设您在表中有一个名为id的主键,(次优)解决方案可能是使用UNION ALL对表进行取消,同时将0值转换为NULL值; then, you can take advantage of aggregate function MIN() , which ignores NULL values. 然后,您可以利用聚合函数MIN() ,它忽略NULL值。

Example query for 5 columns: 5列的示例查询:

SELECT id, MIN(col) lowest
FROM (
    SELECT id, NULLIF(col1, 0) col FROM mytable
    UNION ALL SELECT id, NULLIF(col2, 0) FROM mytable
    UNION ALL SELECT id, NULLIF(col3, 0) FROM mytable
    UNION ALL SELECT id, NULLIF(col4, 0) FROM mytable
    UNION ALL SELECT id, NULLIF(col5, 0) FROM mytable
) x
GROUP BY id

Demo on DB Fiddle DB Fiddle上的演示

Sample data: 样本数据:

| id  | col1 | col2 | col3 | col4 | col5 |
| --- | ---- | ---- | ---- | ---- | ---- |
| 1   | 1    | 2    | 3    | 4    | 5    |
| 2   | 0    | 6    | 7    | 8    | 9    |
| 3   | 0    | 10   | 11   | 12   |      |

Results: 结果:

| id  | lowest |
| --- | ------ |
| 1   | 1      |
| 2   | 6      |
| 3   | 10     |

If there's a maximum possible value for the columns, you can replace any zero values with something above this maximum before calling LEAST . 如果列的最大可能值,则可以在调用LEAST之前将任何零值替换为高于此最大值的值。 Then it will return the value of the least column that's lower than this maximum. 然后它将返回低于此最大值的最小列的值。

In the code below, I assume 999999 is large enough. 在下面的代码中,我假设999999足够大。

SELECT least(
    IF(IFNULL(col_1,0) = 0, 999999, col_1),
    IF(IFNULL(col_2,0) = 0, 999999, col_2),
    IF(IFNULL(col_3,0) = 0, 999999, col_3),
    IF(IFNULL(col_4,0) = 0, 999999, col_4),
    IF(IFNULL(col_5,0) = 0, 999999, col_5),
    IF(IFNULL(col_6,0) = 0, 999999, col_6),
    IF(IFNULL(col_7,0) = 0, 999999, col_7),
    IF(IFNULL(col_8,0) = 0, 999999, col_8),
    IF(IFNULL(col_9,0) = 0, 999999, col_9),
    IF(IFNULL(col_10,0) = 0, 999999, col_10),
    IF(IFNULL(col_11,0) = 0, 999999, col_11),
    IF(IFNULL(col_12,0) = 0, 999999, col_12),
    IF(IFNULL(col_13,0) = 0, 999999, col_13),
    IF(IFNULL(col_14,0) = 0, 999999, col_14),
    IF(IFNULL(col_15,0) = 0, 999999, col_15),
    IF(IFNULL(col_16,0) = 0, 999999, col_16)) as lowest
FROM `my_date_table` 
where date_id = '108'

One relatively simple (but expensive) method is to unpivot and aggregation: 一种相对简单(但价格昂贵)的方法是展开和聚合:

select min(col), max(col)
from ((select col_1 as col from t) union all
      (select col_2 as col from t) union all
      . . .
      (select col_16 as col from t) 
     ) c
where col <> 0;

If you want to express this using least() , you can use coalesce() with nullif() : 如果你想表达这种使用least()你可以使用coalesce() nullif()

select nullif( least( coalesce(nullif(col_1, 0), 999999),
                      coalesce(nullif(col_2, 0), 999999),
                      . . .
                    ), 999999
              )

This assumes that you have some reasonable maximum value to use for 999999 . 这假设您有一些合理的最大值可用于999999

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM