Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 无法使案例适用于空替换。_Mysql_Sql - Fatal编程技术网

Mysql 无法使案例适用于空替换。

Mysql 无法使案例适用于空替换。,mysql,sql,Mysql,Sql,我的代码示例如下: 我想查找已经开始的合同,可能有也可能没有结束日期。如果结束日期晚于今天,或者尚未指定(NULL/empty),则很好 SELECT ID, BeginDate, EndDate, CASE WHEN EndDate IS NULL THEN curdate()+1 END as FinishDate FROM contracts WHERE (id=1) AND (CURDATE() BETWEEN BeginDate an

我的代码示例如下:

我想查找已经开始的合同,可能有也可能没有结束日期。如果结束日期晚于今天,或者尚未指定(NULL/empty),则很好

SELECT 
   ID, BeginDate, EndDate,
CASE
   WHEN EndDate IS NULL 
    THEN curdate()+1
END as FinishDate
FROM 
    contracts
WHERE 
    (id=1) AND
    (CURDATE() BETWEEN BeginDate and FinishDate);
但是我越来越

#1054 - Unknown column 'FinishDate' in 'where clause

我错过了什么

这是因为
FinishDate
不是原始表的一列,因此其标识符的范围仅限于
orderby
子句;它不能用于
WHERE
子句中

有几种方法可以解决这个问题。最简单的方法是将表达式复制到
WHERE
子句中:

SELECT 
   ID, BeginDate, EndDate,
CASE
   WHEN EndDate IS NULL 
    THEN curdate()+1
END as FinishDate
FROM 
    contracts
WHERE 
    (id=1) AND
    (CURDATE() BETWEEN (CASE WHEN EndDate IS NULL THEN curdate()+1 END) and FinishDate);
SELECT ID, BeginDate, EndDate,
       (CASE WHEN EndDate IS NULL 
             THEN curdate()+1
        END) as FinishDate
FROM contracts
WHERE (id=1)
HAVING (CURDATE() BETWEEN BeginDate and FinishDate);
注意:大多数RDBMS都有一个特殊的操作符来提供空替换表达式。在MS SQL Server中,
合并
为空

SELECT 
   ID, BeginDate, EndDate,
   ISNULL(EndDate, curdate()+1) as FinishDate
FROM 
    contracts
WHERE 
    (id=1) AND
    (CURDATE() BETWEEN ISNULL(EndDate, curdate()+1) and FinishDate);

在MySQL中,您实际上可以将条件移动到
having
子句:

SELECT 
   ID, BeginDate, EndDate,
CASE
   WHEN EndDate IS NULL 
    THEN curdate()+1
END as FinishDate
FROM 
    contracts
WHERE 
    (id=1) AND
    (CURDATE() BETWEEN (CASE WHEN EndDate IS NULL THEN curdate()+1 END) and FinishDate);
SELECT ID, BeginDate, EndDate,
       (CASE WHEN EndDate IS NULL 
             THEN curdate()+1
        END) as FinishDate
FROM contracts
WHERE (id=1)
HAVING (CURDATE() BETWEEN BeginDate and FinishDate);
这是一个MySQL扩展,允许您使用
select
中定义的列别名进行筛选。顺便问一下,你确定逻辑正确吗?你真的希望它是:

SELECT ID, BeginDate, EndDate, COALESCE(EndDate, curdate() + 1) as FinishDate

不同之处在于,当
EndDate
有值时,您的版本将
NULL
放入
FinishDate
。此版本使用
EndDate
如果可用,并在不可用时替换“明天”。

别名不适用于根据注释(以及
CURDATE()
的语法)将sql server标记更改为mysql的语句。我还需要第一个Case语句吗?我实际上不需要“FinishDate”-这只是一种变通方法。(这里是MySQL顺便说一句)@Maxcot在
MySQL
中你可以使用
COALESCE(EndDate,curdate()+1)
。如果输出中不需要
FinishDate
,可以将其从
select
列表中删除。+1…这是对SQL Server的一个很好的解释,该问题最初是针对SQL Server的。感谢dasblinkenlight…了解了一些新内容,也正是我在寻找的。(合并)另一个要点是:基础表结构必须允许结束日期字段为NULL。在使用PHP时,我挣扎了一段时间,直到我发现我的字段值不是NULL而是0000-00-00。