SQL错误-列不存在(在“选择为”中)

SQL错误-列不存在(在“选择为”中),sql,postgresql,activerecord,Sql,Postgresql,Activerecord,我加入了两个表格:品种+品种特征(bc) 但我得到了以下错误: PG::UndefinedColumn:错误:第11行不存在列“val” 我不确定出了什么问题,这是我的SQL: SELECT breeds.*, CASE

我加入了两个表格:品种+品种特征(bc)

但我得到了以下错误:

PG::UndefinedColumn:错误:第11行不存在列“val”

我不确定出了什么问题,这是我的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执行此查询)

您不能在
where
子句中使用表达式别名
val

这是因为SQL标准中规定了SQL的执行顺序。这里,
WHERE
子句在
SELECT
之前进行计算,因此,
WHERE
子句不知道您在
SELECT
中创建的别名。
orderby
位于
SELECT
之后,因此可以使用别名

只需将别名替换为实际大小写表达式,如下所示:

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
子句中使用别名。

避免在多个位置重复
大小写表达式的一个选项是使用子查询:

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

错误是正确的。您需要使用子查询或CTE才能使用
选择中定义的值。戈登:我不明白为什么-这是由于内部联接造成的吗?谢谢。你能解释一下为什么where条款不接受它吗?我需要修改你的答案,因为它在WHERE子句中不适用于case参数。我把它改成:…>如果bc.user_val为NULL,则bc.value ELSE(bc.value+(bc.user_val/2))/2结束…好的,谢谢您的澄清。现在我不明白为什么解析器在SELECT之前计算WHERE子句。这似乎违反直觉,因为WHERE可以引用SELECT中别名的列。