2016-12-31 39 views
1

我將兩個表:品種 + breed_characteristics(BC)SQL錯誤 - 列不存在(在SELECT AS)

但我發現了以下錯誤:

PG::UndefinedColumn: ERROR: column "val" does not exist LINE 11

我不知道什麼是錯的,這是我的SQL:

SELECT                  
    breeds.*,                 
    CASE bc.user_val               
    WHEN NULL THEN bc.value             
    ELSE (bc.value + (bc.user_val/2))/2          
    END AS val                 
    FROM                   
    breed_characteristics bc  
    INNER JOIN breeds ON breeds.id = bc.breed_id         
    WHERE bc.characteristic_id = 45        
    AND val BETWEEN 4 AND 5        
    ORDER BY val DESC 

(通過執行活動記錄上的Postgres此查詢)

+0

的錯誤是正確的。您需要使用子查詢或CTE才能使用'SELECT'中定義的值。 –

+0

Gordon: 我很困惑,爲什麼 - 這是由於內部連接? – T1000

回答

3

您不能在where子句中使用表達式別名val

這是因爲SQL標準中指定了執行SQL的順序。這裏,在SELECT之前評估WHERE子句,因此,WHERE子句不知道您在SELECT中創建的別名。 ORDER BYSELECT之後,因此可以使用別名。

只是這樣的實際情況下,表達式替換別名:

SELECT                  
    breeds.*,                 
    CASE bc.user_val               
    WHEN NULL THEN bc.value             
    ELSE (bc.value + (bc.user_val/2))/2          
    END AS val                 
    FROM                   
    breed_characteristics bc  
    INNER JOIN breeds ON breeds.id = bc.breed_id         
    WHERE bc.characteristic_id = 45        
    AND CASE WHEN bc.user_val is NULL THEN bc.value             
    ELSE (bc.value + (bc.user_val/2))/2          
    END BETWEEN 4 AND 5        
    ORDER BY val DESC 

但是,您可以在order by子句中使用別名。爲了避免在多個地方重述CASE表達

+0

謝謝。你能解釋爲什麼where子句不會接受它嗎? 我需要修改您的答案,因爲它不在WHERE子句中使用case參數。我把它改爲: ... > 和CASE WHEN bc.user_val爲null,則bc.value ELSE(bc.value +(bc.user_val/2))/ 2 END ... – T1000

+0

好謝謝澄清。 現在我很困惑爲什麼解析器在SELECT之前評估WHERE子句。這似乎違反直覺,因爲WHERE可能引用SELECT中的別名列。 – T1000

0

一種選擇是使用子查詢:

SELECT * 
FROM 
(
    SELECT b.*, 
      bc.characteristic_id, 
      CASE WHEN bc.user_val IS NULL THEN bc.value 
       ELSE (bc.value + (bc.user_val/2))/2          
      END AS val        
    FROM breed_characteristics bc  
    INNER JOIN breeds b 
     ON breeds.id = bc.breed_id 
) t 
WHERE t.characteristic_id = 45 AND 
     t.val BETWEEN 4 AND 5        
ORDER BY t.val DESC