0

我正在使用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'
4

2 回答 2

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))
于 2013-09-02T08:28:27.240 回答
1

您不需要 - 而且效率不高 - 进行此转换以应用WHEREorHAVING条件。您可以更改条件以处理表列:

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 ...条件,如果有可用于此条件的索引,则查询将是有效的。所有其他计算都在选定的行上执行。
  • 计算的列 - 无论是CASE还是IFNULL()无关紧要CALESCE()-不是针对表的所有行计算的,仅针对选定的行。
  • DATE_FORMAT()功能不需要应用,而不是一次。
于 2013-09-02T08:59:33.203 回答