我想在我的SQL查询中实现以下逻辑:
如果未设置某个日期或其年份为1970年,则选择real_date
标记为空并将日期更改为当前数据,否则 - real_date
为true
且无需更改日期。
real_date
不是表中的实际字段,而是我需要设置的标志。
我可以使用SELECT
部分中的2行轻松完成此操作:
, IF (actualDate is NULL OR YEAR(actualDate) = 1970, CURRENT_TIMESTAMP(), actualDate) as actual_date
, IF (actualDate is NULL OR YEAR(actualDate) = 1970, null, true) as real_date
问题是 - 这是唯一的方法吗?真的不喜欢我不得不再次复制条件的事实。可以以某种方式将第二个选择移动到第一个选择吗?
更新:我需要选择actualDate
(它将固定为当前时间版本或实际存储的值)和real_date
(这将是真的或假/空)。也许我错过了一些东西,但COALESCE功能如何在这里提供帮助呢?
更新2:再次感谢大家。学到了其他写作方法,但所有这些方法都有2个位置。我的想法是只在一个地方有逻辑条件,但似乎不可能。
答案 0 :(得分:1)
您可以使用COALESCE功能。
返回列表中的第一个非NULL值,如果没有非NULL值,则返回NULL。
答案 1 :(得分:1)
您还可以使用CASE WHEN ... THEN ... END
(多个WHEN)代替两个IF
` 请在此处查看:http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html
但COALESCE功能可以完成这种情况。
答案 2 :(得分:1)
我可能会尝试这样的事情:
…
, COALESCE(NULLIF(actualDate, '1970-01-01'), CURRENT_TIMESTAMP()) AS actual_date
, NULLIF(actualDate <> '1970-01-01', false) AS is_real_date
…
或者第二个NULLIF()
可能不是真的必要吗?考虑一下:
…
, COALESCE(NULLIF(actualDate, '1970-01-01'), CURRENT_TIMESTAMP()) AS actual_date
, (actualDate <> '1970-01-01') AS is_real_date
…
第二列可以是true
,false
或NULL
,您可以将NULL
视为false
。
答案 3 :(得分:1)
您的变体非常适合将来支持代码,不要更改任何内容。
答案 4 :(得分:1)
这是我能想到的使用COALESCE
并且不重复任何比较的最紧凑的形式:
select id, type, real_date, if(real_date, actual_date, now()) as actual_date
from (
select *, coalesce(year(actual_date), 1970) != 1970 as real_date from table1
) as subResult
工作example