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

Php 如何使用mysql从多个列中获取最小值,但忽略0作为最小值?,php,mysql,sql,Php,Mysql,Sql,我试图从16列中获取结果,以查找哪一列具有最小值,但最小值不应为0 因此,基于一些建议,我尝试了下面这样的查询,但它不适用于我,因为它返回0 选择最小值( 如果为空(col_1,0), 如果为空(col_2,0), 如果为空(col_3,0), 如果为空(col_4,0), 如果为空(列5,0), 如果为空(列6,0), 如果为空(col_7,0), 如果为空(列8,0), 如果为空(列9,0), 如果为空(列10,0), 如果为空(col_11,0), 如果为空(col_12,0), 如果为空

我试图从16列中获取结果,以查找哪一列具有最小值,但最小值不应为0

因此,基于一些建议,我尝试了下面这样的查询,但它不适用于我,因为它返回0

选择最小值(
如果为空(col_1,0),
如果为空(col_2,0),
如果为空(col_3,0),
如果为空(col_4,0),
如果为空(列5,0),
如果为空(列6,0),
如果为空(col_7,0),
如果为空(列8,0),
如果为空(列9,0),
如果为空(列10,0),
如果为空(col_11,0),
如果为空(col_12,0),
如果为空(col_13,0),
如果为空(col_14,0),
如果为空(列15,0),
IFNULL(col_16,0))为最低
从“我的约会表”
其中date_id='108'

谢谢,请不要标记为重复问题,因为我已经讨论了一些堆栈问题,但找不到可以应用于php/mysql查询的正确解决方案。

这不是一项容易的任务。您不能简单地将所有
0
s转换为
NULL
s,因为
LEAST()
如果其任何参数为
NULL
,则返回
NULL

如果预先知道所有列的最大值,可以使用注释的技巧

否则,假设表中有一个名为
id
的主键,一个(次优)解决方案可以是使用
UNION ALL
取消激活表,同时将
0
值设置为
NULL
值;然后,您可以利用聚合函数
MIN()
,该函数忽略
NULL

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

样本数据:

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

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

如果列有一个可能的最大值,您可以在调用
LEAST
之前用高于该最大值的值替换任何零值。然后,它将返回小于此最大值的最小列的值

在下面的代码中,我假设
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'
一种相对简单(但昂贵)的方法是取消PIVOT和聚合:

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;

这假设您有一些合理的最大值可用于
999999

,但最小值不应为0
。。。你能解释一下这到底意味着什么吗?我想这意味着最小值,不包括任何零值。列是否有最大可能值?您可以使用
最小值(如果(col_1=0,max+1,col_1),…)
一个类似的值作为参考:对不起,我无法使用列的任何最大可能值&@RevathiGanesh您提供的参考并没有返回错误的结果。嗯……这是一种工作,但正在寻找一些简单的解决方案,就像想象16列可以做到这一点一样。@Jimil:我明白。。。但是到目前为止,我想不出更短或更优雅的解决方案…它可以工作,但是你认为它会增加查询的负载吗只是一个问题tho,如果我的最大值和最小值是一样的,例如,有人输入最大值为20,最小值也是20,那么你认为你的解决方案会工作吗?-只要问一下,它就会返回20。
999999
应该是不可能出现在表中的东西。这基本上是我和GMB的答案。但是您的代码不处理表中的实际空值。
select nullif( least( coalesce(nullif(col_1, 0), 999999),
                      coalesce(nullif(col_2, 0), 999999),
                      . . .
                    ), 999999
              )