我以前的问题和解决方案:
这个工作正常,但我想在这个例子中跳过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的最佳方法?
答案 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
然后,通过每个first
(GROUP 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
的所有四列都包含NULL
或0
,则最小值和最大值将显示为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。我们可能需要针对该案例进行调整。