将MySQL select转换为PostgreSQL

Bri*_*ong 14 mysql sql postgresql

我有这个查询在MySQL中正常工作.更多背景信息在这里.

SELECT c.*, SUM(ABS(v.vote)) AS score
FROM categories c,items i, votes v
    WHERE c.id = i.category_id
    AND i.id = v.voteable_id
    AND v.created_at > '#{1.week.ago}'
GROUP BY c.id
ORDER BY score DESC LIMIT 8;
Run Code Online (Sandbox Code Playgroud)

我尝试在PostgreSQL中运行它,它失败了这个错误消息.

PGError:错误:列"c.name"必须出现在GROUP BY子句中或用于聚合函数

我不确定这是什么意思,所以我尝试在group by子句中将"c.id"更改为"c.name"(假设项目的名称是唯一的,两者在MySQL中的工作方式相同).

然而,这只是产生了另一个类似的错

PGError:错误:列"c.id"必须出现在GROUP BY子句中或用于聚合函数

如何解决这个问题?

tef*_*ozi 11

您必须在SELECT中列出要分组的列名:

SELECT c.id, c.name, SUM(ABS(v.vote)) AS score
FROM categories c,items i, votes v
  WHERE c.id = i.category_id
  AND i.id = v.voteable_id
  AND v.created_at > '#{1.week.ago}'
GROUP BY c.id, c.name
ORDER BY score DESC LIMIT 8;
Run Code Online (Sandbox Code Playgroud)

"不允许在SELECT子句中包含未在GROUP BY子句中引用的列名."

  • 它在MySQL中是允许的,这就是为什么他感到困惑.我认为可怕的特征 (9认同)

col*_*ium 8

我只是遇到了这个问题但是从MySQL到SQL Server.我认为这是允许的,这很奇怪!

是的,在大多数数据库中,当您拥有GROUP BY子句时,您只能选择GROUP BY子句中出现的列或列的聚合.这是因为它无法知道您选择的其他列是否真正唯一.

如果它们确实是唯一的,只需将所需的列放在GROUP BY中即可.这是MySQL的一个"功能",值得怀疑.

您可以在这里阅读MySQL的行为以及它的不同之.

例:

SELECT c.*, SUM(ABS(v.vote)) AS score
FROM categories c,items i, votes v
    WHERE c.id = i.category_id
    AND i.id = v.voteable_id
    AND v.created_at > '#{1.week.ago}'
GROUP BY c.id, c.name, c.whatever_else
ORDER BY score DESC LIMIT 8;
Run Code Online (Sandbox Code Playgroud)