在SQL查询的'WHERE'子句中的'SELECT'中使用'IF'的结果

时间:2016-12-07 12:09:37

标签: mysql sql

我们有以下查询:

SELECT
        foo_id,
        IF (( SELECT
            COUNT(foo_mapping_id) 
        FROM
            foo_bar_mappings,
            bar
        WHERE
            foo_mapping_foo_id = foo_id
            AND foo_mapping_bar_id = bar_id ) > 0,
        foo_status,
        'inactive') AS foo_status
    FROM
        foo
    WHERE
        foo_status = 'inactive'

当我们运行它时,我们得到一个空结果,因为foo_status不等于inactive(而有些行满足IF)。 foo_statusfoo表中存在的列,但我们想要“覆盖”它。

我们如何更改此查询,以便我们可以使用foo_status条款中IF返回的WHERE?显然,这个查询已被简化,使问题更易于提问和理解。

2 个答案:

答案 0 :(得分:3)

您不能在where子句中使用列别名。 MySQL 扩展了HAVING子句,因此可以使用它:

having foo_status = 'inactive'

注意:

我会将查询写成:

SELECT f.foo_id,
       (CASE WHEN (EXISTS (SELECT 1
                           FROM foo_bar_mappings fb JOIN
                                bar b
                                ON fb.foo_mapping_bar_id = b.bar_id
                           WHERE fb.foo_mapping_foo_id = f.foo_id
                          ) 
             THEN foo_status
             ELSE 'inactive'
         END) AS new_foo_status
FROM foo f
HAVING new_foo_status = 'inactive';

注意:

    在此上下文中,
  • EXISTSCOUNT(*)效率更高。
  • 我更喜欢CASEIF(),因为前者是ANSI标准。
  • 我使用与真实列名称相同的列别名感到很不舒服。使用别名时,这可能会造成混淆。

答案 1 :(得分:0)

正如在其他答案中已经建议的那样,您可以使用HAVING子句中的列别名,但我发现您在发布的查询中没有GROUP BY。在这种情况下,您可以在外部查询中使用别名列,例如

SELECT * FROM (
SELECT
        foo_id,
        IF (( SELECT
            COUNT(foo_mapping_id) 
        FROM
            foo_bar_mappings,
            bar
        WHERE
            foo_mapping_foo_id = foo_id
            AND foo_mapping_bar_id = bar_id ) > 0,
        foo_status,
        'inactive') AS foo_status
    FROM
        foo ) xxx
    WHERE
        foo_status = 'inactive'