2016-12-07 32 views
1

我们有以下查询:使用结果

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_status是存在于foo表中的列,但我们想要“覆盖”它。

我们将如何更改此查询,以便我们可以使用foo_status,如在WHERE条款中返回的那样?很明显,这个查询已经被简化,使问题更容易提问和理解。

回答

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标准。
  • 我很不舒服,使用与真实列具有相同名称的列别名。使用别名时可能会造成混淆。
+0

但'拥有'没有任何'group by'。是否有意义? – Rahul

+2

@Rahul。 。 。它在MySQL中是因为这个扩展。我认为扩展的存在是因为MySQL实现了子查询(其他数据库不一定这样做),所以这是一种不使用子查询就可以进行过滤的方法。 –

+0

啊!现在有道理。现在明白了。 – Rahul

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'