12

作为 Postgresql 的新手(我要搬家是因为我将我的网站移动到只支持它的 heroku,我不得不重构我的一些查询和代码。这是一个我不太明白的问题和:

PGError: ERROR:  column "l_user_id" does not exist
LINE 1: ...t_id where l.user_id = 8 order by l2.geopoint_id, l_user_id ...
                                                             ^

...询问:

   select distinct 
          l2.*, 
          l.user_id as l_user_id, 
          l.geopoint_id as l_geopoint_id 
     from locations l 
left join locations l2 on l.geopoint_id = l2.geopoint_id 
    where l.user_id = 8 
 order by l2.geopoint_id, l_user_id = l2.user_id desc

添加了子句“l.user_id as l_user_id, l.geopoint_id as l_geopoint_id”,因为显然 postgres 不喜欢未选择字段的 order 子句。但是我现在得到的错误使它看起来我也没有得到别名。有postgres经验的人看到这个问题吗?

我可能会遇到很多这样的问题——查询在 mySql 中运行良好......

4

4 回答 4

16

在 PostgreSQL 中,您不能按顺序使用带有别名的表达式。只有普通别名在那里工作。您的查询应如下所示:

   select distinct 
          l2.*, 
          l.user_id as l_user_id, 
          l.geopoint_id as l_geopoint_id 
     from locations l 
left join locations l2 on l.geopoint_id = l2.geopoint_id 
    where l.user_id = 8 
 order by l2.geopoint_id, l.user_id = l2.user_id desc;

我想你的意思是l2.user_id=l.user_id应该先去。

这是PostgreSQL 通用邮件列表上的相关消息。以下是在条款的文档中ORDER BY

每个表达式可以是输出列(SELECT 列表项)的名称或序号,也可以是由输入列形成的任意表达式

所以使用表达式时没有别名。

于 2009-10-30T15:28:11.173 回答
5

我使用来自fuzzystrmatch 的函数遇到了同样的问题——尤其是levenshtein 函数。我需要按字符串距离排序,并按字符串距离过滤结果。我最初是在尝试:

SELECT thing.*, 
levenshtein(thing.name, '%s') AS dist 
FROM thing 
WHERE dist < character_length(thing.name)/2 
ORDER BY dist

但是,当然,我从 WHERE 子句中得到了错误“列”dist“不存在”。我试过了,它奏效了:

SELECT thing.*, 
(levenshtein(thing.name, '%s')) AS dist 
FROM thing 
ORDER BY dist

但是我需要在 WHERE 子句中具有该资格。这个问题中的其他人说,在 ORDER BY 之前评估了 WHERE 子句,因此在评估 WHERE 子句时该列不存在。按照这个建议,我发现嵌套的 SELECT 语句可以解决问题:

SELECT * FROM 
(SELECT thing.*, 
     (levenshtein(thing.name, '%s')) AS dist 
     FROM thing 
     ORDER BY dist
) items 
WHERE dist < (character_length(items.name)/2)

请注意,“items”表别名是必需的,并且 dist 列别名可在外部 SELECT 中访问,因为它在语句中是唯一的。这有点时髦,我很惊讶在 PG 中它必须是这种方式 - 但它似乎并没有受到性能影响,所以我很满意。

于 2012-04-11T02:18:14.683 回答
4

你有:

order by l2.geopoint_id, l_user_id = l2.user_id desc

在您的查询中。那是非法的语法。移除部件(如果这是连接条件之一,则将= l2.user_id其移至)它应该可以工作。where

更新下面的选择(= l2.user_id删除)应该可以正常工作。我已经在 Postgres 8.3 上测试过它(显然有不同的表/列名)

select distinct 
       l2.*, 
       l.user_id as l_user_id, 
       l.geopoint_id as l_geopoint_id 
  from locations l 
  left join locations l2 on l.geopoint_id = l2.geopoint_id 
 where l.user_id = 8 
 order by l2.geopoint_id, l_user_id desc
于 2009-10-29T18:20:13.353 回答
1

“被添加是因为显然 postgres 不喜欢未选择字段的 order 子句”

“就 order by 而言 - 是的,PostgresQL(和许多其他数据库)不允许按未在 select 子句中列出的列进行排序。”

简直不真实。

=> SELECT id FROM t1 ORDER BY owner LIMIT 5;

ID

30 10 20 50 40(5排)

于 2009-10-29T20:11:03.527 回答