2016-12-07 33 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'