将MySQL查询转换为PostgreSQL的问题

时间:2011-08-10 14:08:40

标签: mysql sql postgresql group-by

我有一个在MySQL上运行良好的查询,现在在PostgreSQL上没有 这是查询:

  SELECT "users".* 
    FROM "users" 
    JOIN "favorites" ON "favorites"."user_id" = "users"."id"
   WHERE users.id NOT IN (2)
     AND favorites.favoritable_id IN (1)
GROUP BY favorites.user_id 
ORDER BY RANDOM() 
   LIMIT 5

这是错误:

  

列“users.id”必须出现在GROUP BY子句中或用于聚合函数

我查了一下这个错误,但无法找到我必须要解决的问题。

3 个答案:

答案 0 :(得分:5)

对于GROUP BY - 子句,MySQL非常松懈。在MySQL中,您可以向select子句中添加不在GROUP BY中的列或聚合函数。其他RDBMS不允许这样做,因为它在语义上没有意义。 MySQL只返回适合给定查询的或多或少的随机行值。

来自MySQL Doc

  

在标准SQL中,包含GROUP BY子句的查询不能引用选择列表中未在GROUP BY子句中指定的非聚合列。 [...]   MySQL扩展了GROUP BY的使用,因此选择列表可以引用GROUP BY子句中未命名的非聚合列。

您需要做的是,找出查询应该执行的操作并重写它。

答案 1 :(得分:4)

MySQL(以及SQLite)不要求您指定GROUP BY子句中未包含在聚合函数中的每一列(IE:MIN,MAX,COUNT,SUM等)。这是by design,也是ANSI规范。但是,这意味着这些列的值将是任意的 - 每次运行查询时都无法保证这些值。

PostgreSQL / Oracle / SQL Server要求您指定未包含在组中的聚合函数中的每个列,或者重新编写查询以使其不必要。使用:

  SELECT u.*
    FROM USERS u
   WHERE EXISTS (SELECT NULL
                   FROM FAVORITES f
                  WHERE f.user_id = u.id
                    AND f.favoritable_id = 1)
     AND u.id != 2
ORDER BY RANDOM()
   LIMIT 5

答案 2 :(得分:0)

PostgreSQL中的另一个选项是distinct子句:

从用户中选择(col1,col2)*上的distinct;

这将完成mysql正在做的事情。