如何在SQL中的某个特定行中查找最少的非空列?
我试图找到同一个表中某一行的两列中的最小数字,并注意其中一列可能在特定行中为空。如果其中一列为空,我希望为该行返回另一列中的值,因为这是此例中最低的非空列。如果我使用MySQL 5.1中最少()函数:如何在SQL中的某个特定行中查找最少的非空列?
select least(1,null)
这将返回null,这不是我想要的。在这种情况下,我需要查询返回1。
我已经能够得到我想要的,一般与此查询结果:
select least(coalesce(col1, col2)) , coalesce(col2,col1))
只要col1和col2上都是不为空每个凝聚语句将返回一个数字,最少( )处理找到最低。
有没有更简单/更快的方法来做到这一点?在这种情况下,我使用的是MySQL,但欢迎使用一般解决方案。
不幸(对于你的情况)LEAST的行为在MySQL 5.0.13(http://dev.mysql.com/doc/refman/5.0/en/comparison-operators.html#function_least)中发生了变化 - 只有在所有参数都为NULL的情况下,它才返回NULL。
这个变化甚至被报告为一个bug:http://bugs.mysql.com/bug.php?id=15610 但是这个修复只是为了解释新的行为和兼容性问题。
您的解决方案是推荐的解决方法之一。另一个可以使用IF操作:
SELECT IF(Col1 IS NULL OR Col2 IS NULL, COALESCE(Col1, Col2), LEAST(Col1,Col2))
这可以执行好一点(可能要转换成相应的MySql语法):
SELECT
CASE
WHEN Col1 IS NULL THEN Col2
WHEN Col2 IS NULL THEN Col1
ELSE Least(Col1, Col2)
END
另一种方法(可能比较慢,虽然,但值得一试):
SELECT Col1
WHERE Col2 IS NULL
UNION
SELECT Col2
WHERE Col1 IS NULL
UNION
SELECT least(Col1, Col2)
WHERE Col1 IS NOT NULL AND Col2 IS NOT NULL
根据其所有值是null
的你的角落情况下的情况下,我会去这样的语法,这是更具可读性(如果你恰好有两列一个简单的解决方案是低于!)
SELECT LEAST(IFNULL(5, ~0 >> 1), IFNULL(10, ~0 >> 1)) AS least_date;
-- Returns: 5
SELECT LEAST(IFNULL(null, ~0 >> 1), IFNULL(10, ~0 >> 1)) AS least_date;
-- Returns: 10
SELECT LEAST(IFNULL(5, ~0 >> 1), IFNULL(null, ~0 >> 1)) AS least_date;
-- Returns: 5
SELECT LEAST(IFNULL(null, ~0 >> 1), IFNULL(null, ~0 >> 1)) AS least_date
-- Returns: @MAX_VALUE (If you need to use it as default value)
SET @MAX_VALUE=~0 >> 1;
SELECT LEAST(IFNULL(null, @MAX_VALUE), IFNULL(null, @MAX_VALUE)) AS least_date;
-- Returns: @MAX_VALUE (If you need to use it as default value). Variables just makes it more readable!
SET @MAX_VALUE=~0 >> 1;
SELECT NULLIF(
LEAST(IFNULL(null, @MAX_VALUE), IFNULL(null,@MAX_VALUE)),
@MAX_VALUE
) AS least_date;
-- Returns: NULL
这是我的,如果
- 可以保证至少有一列首选方式不能
NULL
- 在拐角情况下(所有列都是
NULL
),您希望获得大于任何可能值的非空默认值,或者可以将其限制为某个阈值 - 您可以处理变量以使该语句更具可读性
如果你问自己什么~0 >> 1
的意思是: 这只是一个简短的说“给我最大的数量”。另请参见:https://stackoverflow.com/a/2679152/2427579
更妙的是,如果你只有两列,你可以使用:
SELECT LEAST(IFNULL(@column1, @column2), IFNULL(@column2, @column1)) AS least_date;
-- Returns: NULL (if both columns are null) or the least value
为什么不设置一个列的值等于其他列时,它的空?
SELECT LEAST(IFNULL(COL1, COL2), IFNULL(COL2, COL1));
用上面的代码,空值将被忽略,除非两者都为空。
例如
COL1 = NULL,COL2 = 5
LEAST(IFNULL(NULL, 5), IFNULL(5, NULL)) -> LEAST(5, 5) -> 5
COL1 = 3,COL2 = NULL
LEAST(IFNULL(3, NULL), IFNULL(NULL, 3)) -> LEAST(3, 3) -> 3
COL1 = NULL,COL2 = NULL
LEAST(IFNULL(NULL, NULL), IFNULL(NULL, NULL)) -> LEAST(NULL, NULL) -> NULL
快?你确定它慢? – 2010-06-20 06:03:05
还没有判断它一定很慢,但它调用了3个函数,而不是可能的一个。我在按照我需要尽可能快的查询的子句中使用它。 – 2010-06-20 06:08:44