在SQL中跳过0和NULL

时间:2012-07-09 09:50:54

标签: php mysql sql

我以前的问题和解决方案:

Get max and min from fields

这个工作正常,但我想在这个例子中跳过0和NULL。

例如:

First:
id | title 
1  | aaa
2  | bbb
3  | ccc

Second:
id | first_id | one | two    | three | four
1  |    1     | 3   | 0      | 4     | 6
2  |    2     | 4   | 4      | 1     | 2
3  |    3     | 1   | NULL   | 3     | 4

这应该告诉我:

id | title | min | max 
1  | aaa   |  3  | 6
2  | bbb   |  1  | 4
3  | ccc   |  1  | 4

id | title | min | max 
1  | aaa   |  0  | 6
2  | bbb   |  1  | 4
3  | ccc   |  0  | 4

我上一个问题的哪个例子是实现跳过0和NULL的最佳方法?

5 个答案:

答案 0 :(得分:1)

将这些内容放入您的条款

SELECT 
    f.id, 
    f.title
    MIN(LEAST(greatest(coalesce(s.one,0),1), greatest(coalesce(s.two,0),1), greatest(coalesce(s.three,0),1), greatest(coalesce(s.four,0),1))) as min,
    MAX(GREATEST(greatest(coalesce(s.one,0),1), greatest(coalesce(s.two,0),1), greatest(coalesce(s.three,0),1), greatest(coalesce(s.four,0),1))) as max
FROM 
    First f
        INNER JOIN Second s
        on f.id = s.first_id
GROUP BY 
    f.id, 
    f.title

您可以使用coalesce(fieldName, 1)将空值变为1。

同样,正如您在上一个问题中所述,这是强制使用查询来强制回答。您应该更改数据库的布局。

编辑:我已经确定了你想要的数据,但在你看之前,请注意如果我的一位同事写了这样的剧本,他就会被当场解雇。这是隐藏的,不应该使用。

select
    f.id,
    f.title,
    (select min(z.myVal) from
        (
select
    b.id,
    b.first_id,
    b.one as myVal
from
    second b
where
    b.one is not null
    and b.one > 0
union
select
    b.id,
    b.first_id,
    b.two as myVal
from
    second b
where
    b.two is not null
    and b.two > 0
union
select
    b.id,
    b.first_id,
    b.three as myVal
from
    second b
where
    b.three is not null
    and b.three > 0
union
select
    b.id,
    b.first_id,
    b.four as myVal
from
    second b
where
    b.four is not null
    and b.four > 0
        ) z
    where
    f.id=z.first_id) as miniVal,
    greatest(
        coalesce(s.one,0),
        coalesce(s.two,0),
        coalesce(s.three,0),
        coalesce(s.four,0)  
    ) as maxiVal
from
    first f,
    second s
where
    f.id=s.first_id

输出数据

+------+-------+---------+---------+
| id   | title | miniVal | maxiVal |
+------+-------+---------+---------+
|    1 | aaaa  |       3 |       6 |
|    2 | bbbb  |       1 |       4 |
|    3 | cccc  |       1 |       4 |
+------+-------+---------+---------+
3 rows in set (0.00 sec)

运行这个查询让我呕吐在嘴里。这就是写这样的SQL的错误。

答案 1 :(得分:1)

虽然看似笨重,但这个解决方案应该有效:

SELECT 
    a.id, a.title, MIN(b.num) AS min, MAX(b.num) AS max
FROM 
    first a
LEFT JOIN
(
    SELECT first_id, one AS num FROM second UNION ALL
    SELECT first_id, two FROM second UNION ALL
    SELECT first_id, three FROM second UNION ALL
    SELECT first_id, four FROM second 
) b ON 
    a.id = b.first_id AND 
    b.num IS NOT NULL AND 
    b.num > 0
GROUP BY 
    a.id, a.title

这样做实际上是将每个数字列放入其自己的行中,但 非空的数字> 0.在GROUP BY之前,LEFT JOIN的结果如下所示:

id  |  title  |  num
---------------------
1   |  aaa    |  3
1   |  aaa    |  4
1   |  aaa    |  6
2   |  bbb    |  1
2   |  bbb    |  2
2   |  bbb    |  4
2   |  bbb    |  4
3   |  ccc    |  1
3   |  ccc    |  3
3   |  ccc    |  4

然后,通过每个firstGROUP BY a.id, a.title)的分组,我们可以使用MIN()列上的MAX()num聚合函数来提取最小值和first组的最大值:

id  |  title  |  min  |  max
----------------------------
1   |  aaa    |  3    |  6
2   |  bbb    |  1    |  4
3   |  ccc    |  1    |  4

如果first_id的所有四列都包含NULL0,则最小值和最大值将显示为NULL,因为使用LEFT JOIN代替INNER JOIN因为我认为这对您的情况会更好:

id  |  title  |  min  |  max
----------------------------
4   |  ddd    |  NULL |  NULL

答案 2 :(得分:0)

使用:

WHERE COLUMN IS NOT NULL AND COLUMN <> 0;

答案 3 :(得分:0)

您可以使用IFNULL()

WHERE IFNULL(fieldname, 0) != 0

答案 4 :(得分:0)

我认为你只需要嵌套LEAST表达式:

LEAST(
    NULLIF(one,0),
    LEAST(
        NULLIF(two,0),
            LEAST(
                NULLIF(three,0),
                LEAST(
                    NULLIF(four,0),
                    null ))))

编辑我只是查了一下。 LEAST函数有多个参数:

LEAST( NULLIF(one,0), NULLIF(two,0), NULLIF(three,0), NULLIF(four,0))

编辑2 我看到你想要最小和最大。显然,您只需根据需要将LEAST更改为GREATEST或MIN更改为MAX。

这可能更直接,或者您可能没有最便捷的功能。

SELECT
    f.id, f.title,
    (
        SELECT MIN(NULLIF(val, 0))
        FROM
            (
                SELECT one AS val UNION ALL
                SELECT two UNION ALL
                SELECT three UNION ALL
                SELECT four
            ) AS vals
        ) 
    ) as minval

FROM First f INNER JOIN Second s on f.id = s.first_id

您还没有指定所有四列是否可以为null / 0。我们可能需要针对该案例进行调整。