在CASE语句后应用WHERE?

时间:2013-09-02 08:24:37

标签: mysql select case where

我正在使用CASE语句为某些日期过滤构建我的查询,但在获得正确的CASE语法后,我无法设法应用WHERE语句

所以,我想知道,我怎么能这样做?

我的实际代码是:

SELECT id, fecha_inicio,
    CASE WHEN eventos.fecha_fin IS NULL
        THEN DATE_ADD(eventos.fecha_inicio, INTERVAL 45 DAY)
        ELSE fecha_fin
    END as fecha_fin_new
FROM eventos
WHERE DATE_FORMAT(fecha_fin_new, '%Y-%m') >= '2006-01'

2 个答案:

答案 0 :(得分:1)

WHERE只能与表值一起使用。要处理SELECT别名,您必须使用HAVING

SELECT id, fecha_inicio,
    CASE WHEN eventos.fecha_fin IS NULL
        THEN DATE_ADD(eventos.fecha_inicio, INTERVAL 45 DAY)
        ELSE fecha_fin
    END as fecha_fin_new
FROM eventos
HAVING DATE_FORMAT(fecha_fin_new, '%Y-%m') >= '2006-01'

您还可以将CASE表达式替换为:

IFNULL(fecha_fin, DATE_ADD(eventos.fecha_inicio, INTERVAL 45 DAY))

答案 1 :(得分:1)

执行此转换以应用WHEREHAVING条件时,您不需要 - 并且效率不高。您可以更改条件以处理表列:

WHERE ( eventos.fecha_fin IS NULL
      AND DATE_ADD(eventos.fecha_inicio, INTERVAL 45 DAY) >= '2006-01-01'
      )
   OR ( eventos.fecha_fin IS NOT NULL
      AND fecha_fin >= '2006-01-01'
      )

可以进一步简化/重写为:

WHERE eventos.fecha_fin IS NULL
      AND eventos.fecha_inicio >= DATE_SUB('2006-01-01', INTERVAL 45 DAY)
   OR eventos.fecha_fin >= '2006-01-01'

因此,查询可以写成:

SELECT e.id, e.fecha_inicio,
    COALESCE( e.fecha_fin, DATE_ADD(e.fecha_inicio, INTERVAL 45 DAY) )
      AS fecha_fin_new
FROM eventos AS e
WHERE e.fecha_fin IS NULL
      AND e.fecha_inicio >= DATE_SUB('2006-01-01', INTERVAL 45 DAY)
   OR e.fecha_fin >= '2006-01-01'

这样:

  • 首先检查e.fecha_fin IS NULL AND ... OR ...条件,如果有可用于此条件的索引,则查询将是有效的。所有其他计算都在选定的行上执行。
  • 计算列 - 无论是CASEIFNULL()还是CALESCE()无关紧要 - 对于表格的所有行都计算 <选定的。
  • DATE_FORMAT()功能需要应用,而不是一次。