【问题标题】:postgres - partial column in SELECT/GROUP BY - column must appear in the GROUP BY clause or be used in an aggregate functionpostgres - SELECT/GROUP BY 中的部分列 - 列必须出现在 GROUP BY 子句中或在聚合函数中使用
【发布时间】:2009-11-23 02:56:54
【问题描述】:

以下两个语句都会在 Postgres 中产生错误:

SELECT substring(start_time,1,8) AS date, count(*) as total from cdrs group by date;
SELECT substring(start_time,1,8) AS date, count(*) as total from cdrs group by substring(start_time,1,8);

错误是:

列“cdrs.start_time”必须出现在 GROUP BY 子句中或被使用 在聚合函数中

我对 postgres 文档的阅读是 SELECT 和 GROUP BY 都可以使用 表达式 postgres 8.3 SELECT

start_time 字段是一个字符串,具有 ccyymmddHHMMSS 形式的日期/时间。在 mySQL 中,它们都会产生预期和预期的结果:

+----------+-------+
| date     | total |
+----------+-------+
| 20091028 |     9 |
| 20091029 |   110 |
| 20091120 |    14 |
| 20091121 |     4 |
+----------+-------+
4 rows in set (0.00 sec)

我需要坚持使用 Postgres (heroku)。有什么建议吗?

附言还有很多其他讨论讨论 GROUP BY 中缺少的项目以及为什么 mySQL 接受这个,为什么其他人不...严格遵守 SQL 规范等,但我认为这与 1062158/converting-mysql-select-to-postgresql 和 @ 有很大不同987654323@ 保证一个单独的问题。

【问题讨论】:

  • 你会得到相同的行为将语句移植到 SQL Server、Oracle、SQLite...
  • 这不是和1769361不同吗?该问题在 GROUP BY 与 SELECT 中缺少列。但是这个问题在 SELECT 中显示了一个表达式,在 GROUP BY 中显示了相同的表达式。并且 DISTINCT ON 不会产生正确的结果。
  • 刚刚用 sqlite 做了一个测试,它产生了与 mySQL 相同的结果 ... sqlite> select start_time from fred; 20091020 20091020 20091020 20091021 20091021 20091031 20091031 20091031 20091031 20091031 20091031 20091031 20091031 sqlite> select substr(start_time,1,7) as subdate, count() as total from fred group by substr(start_time,1,7); 2009102|5 2009103|8 sqlite> select substr(start_time,1,7) as subdate, count() as total from fred group by subdate; 2009102|5 2009103|8 sqlite>

标签: sql mysql ruby-on-rails postgresql heroku


【解决方案1】:

您做了其他未在问题中描述的事情,因为您的两个查询都可以正常工作。在 8.5 和 8.3.8 上测试:

# create table cdrs (start_time text);
CREATE TABLE

# insert into cdrs (start_time) values ('20090101121212'),('20090101131313'),('20090510040603');
INSERT 0 3

# SELECT substring(start_time,1,8) AS date, count(*) as total from cdrs group by date;
   date   | total
----------+-------
 20090510 |     1
 20090101 |     2
(2 rows)

# SELECT substring(start_time,1,8) AS date, count(*) as total from cdrs group by substring(start_time,1,8);
   date   | total
----------+-------
 20090510 |     1
 20090101 |     2
(2 rows)

【讨论】:

  • 非常正确,有一个“ORDER BY start_time ASC”子句,我认为它会简化示例,并认为它与错误消息无关。不是这样。更改为“ORDER BY date ASC”或“ORDER BY substring(start_time,1,8) ASC”可以工作并给出正确的结果。请注意,mySQL 和 sqlite 都接受“ORDER BY start_time ASC”和其他两种格式。这是一个误导性的错误消息,但我应该在上面提供完整的查询。感谢您的帮助。
【解决方案2】:

总结一下,错误

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

是由ORDER BY start_time 子句引起的(在这种情况下)。完整的声明需要是:

SELECT substring(start_time,1,8) AS date, count(*) as total FROM cdrs GROUP BY substring(start_time,1,8) ORDER BY substring(start_time,1,8);

    SELECT substring(start_time,1,8) AS date, count(*) as total FROM cdrs GROUP BY date ORDER BY date;

【讨论】:

    【解决方案3】:

    您可以尝试两件简单的事情:

    1. 升级到 postgres 8.4.1
      pg841 下的两个查询Work Just Fine For Me(tm)

    2. 按顺序位置分组
      即在本例中为GROUP BY 1

    【讨论】:

    • re 1.,看heroku什么时候升级! re 2.,刚刚试过,同样的错误。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-16
    • 2020-06-11
    • 2021-06-25
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多