【问题标题】:Group By Issue converting MySQL to PostgreSQL按问题分组将 MySQL 转换为 PostgreSQL
【发布时间】:2016-06-14 17:34:45
【问题描述】:

我正在尝试将旧的 symfony 1.4 应用程序从 MySQL 转换为 PostgreSQL。

我一遍又一遍地遇到同样的问题。

我有一些长连接,它总是抱怨必须有一个 Group By... 在某些情况下,我添加了 Group By,它会要求另一个。

我是 postgres 的新手,我完全不知道发生了什么。

这里是教义查询和错误消息。

    public function getClassifieds($gs_id, $sort_param, $sorter) {

    $q = Doctrine_Query::create()
            ->select('a.*, u.*, t.*,ug.*,ur.*, avg(ur.rating) as rating ')
            ->from('Items a')
            ->leftJoin('a.MonitoredAds ma ON ma.item_id = a.id')
            ->leftJoin('a.GameCategories gc ON gc.game_id = a.game_id')
            ->leftJoin('a.User u ON u.id = a.user_id')
            ->leftJoin('u.Profile ug ON ug.user_id = u.id')
            ->leftJoin('a.UserRatings ur ON ug.user_id = ur.seller_id')
            ->where('a.game_server_id = ?', $gs_id)
            ->andWhere('a.quantity > ?', 0);
    switch ($sorter) {
        case 'datetime_oldest_to_newist':
            $q->orderBy('a.created_at asc');
            break;
        case 'datetime_newest_to_oldest':
            $q->orderBy('a.created_at desc');
            break;
        case 'price_lowest_to_highest':
            $q->orderBy('a.price + 0 ASC');
            break;
        case 'price_highest_to_lowest':
            $q->orderBy('a.price + 0 DESC');
            break;
        case 'quantity_lowest_to_highest';
            $q->orderBy('a.quantity asc');
            break;
        case 'quantity_highest_to_lowest';
            $q->orderBy('a.quantity desc');
            break;
        case 'quantity_highest_to_lowest';
            $q->orderBy('a.quantity desc');
            break;
        case 'sortby_usernameasc':
            $q->orderBy('u.username asc');
            break;
        case 'sortby_usernamedesc':
            $q->orderBy('u.username desc');
            break;
        case 'sortby_userstatus':
            $q->orderBy('ug.user_status asc');
            break;
    }

    return $q;
}

给我这个错误信息

SQLSTATE[42803]:分组错误:7 错误:列“i.id”必须出现在 GROUP BY 子句中或在聚合函数中使用 第 1 行:选择 i.id AS i__id、i.featured AS i__featured、i.status AS...

所以我把代码改成...

   ->andWhere('a.quantity > ?', 0)
        ->groupBy('a.id');

然后我得到一个新的错误...

SQLSTATE[42803]:分组错误:7 错误:列“s.id”必须出现在 GROUP BY 子句中或用于聚合函数 第 1 行:... AS i__created_at, i.updated_at AS i__updated_at, s.id AS s_...

我停在这里是因为这在很大程度上改变了查询的行为,我真的不知道发生了什么。

我不害怕阅读文档,但我什至不知道从哪里开始。

如果您知道可能是什么问题,请告诉我。如果您知道我应该在文档中查找的位置,请也告诉我。

提前谢谢你。

斯科特

【问题讨论】:

  • MySQL 是个例外,所有其他主要的 RDBMS 都需要使用聚合函数(例如 AVG)按结果中包含的所有非聚合字段分组的查询。缺少 group by 完全让我相信连接表与 Items 处于 1:1 关系,或者非聚合字段的结果实际上是接近随机的。

标签: mysql postgresql doctrine symfony-1.4


【解决方案1】:

没有GROUP BYur.rating之外的所有列的PostgreSQL是不正确的:

->select('a.*, u.*, t.*,ug.*,ur.*, avg(ur.rating) as rating ')

每个选择和排序的列都必须在 GROUP BY 或聚合函数中。

例如重写查询:

 ->select('u.id, avg(ur.rating) as rating ')
 ...
 ->orderBy('u.id');
 ->groupBy('u.id');

【讨论】:

  • 谢谢。这消除了错误,但来自其他左连接的数据现在丢失了。 Postgres 中的左连接不一样吗?
  • 我只需要阅读连接。他们似乎有很大的不同
猜你喜欢
  • 2021-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多