【问题标题】:how write a sql request with sql rank function如何使用 sql rank 函数编写 sql 请求(更新)
【发布时间】:2022-11-10 23:18:12
【问题描述】:

如何将此 sql 请求 (cl_rank) 添加到我的请求中?

我的请求(在 ClassementsTable 类中)没有排名:

$classement = $this->find('all')
            ->contain(['Users' => ['fields' => ['id', 'user_login', 'picture']]])
            ->select(['classement', 'points', 'participations'])
            ->order(["Classements.points" => "desc", "Classements.participations" => "asc"])
            ->disableHydration();

我需要这样的 cl_rank:

select user_id, points, 
RANK() over (order by points desc)cl_rank
from classements;

newExpr 可能是一个解决方案:

$query = $this->find('all');
        $expr = $query->newExpr('RANK() over (order by points desc) cl_rank');
        $classement = $query
            ->where(['user_id IN' => $equipe])
            ->contain(['Users' => ['fields' => ['id', 'user_login', 'picture']]])
            ->select(['classement', 'points', 'participations',  $expr])
            ->order(["Classements.points" => "desc", "Classements.participations" => "asc"])
            ->disableHydration();

但是一些额外的 () 在 RANK() 周围添加了(按点 desc 排序)cl_rank 并且 sql 请求不正确。

生成的sql请求:

SELECT Classements.classement AS Classements__classement, 
Classements.points AS Classements__points, 
Classements.participations AS Classements__participations, 
(RANK() over (order by points desc)cl_rank), 
Users.id AS Users__id, 
Users.user_login AS Users__user_login, 
Users.picture AS Users__picture 
FROM classements Classements INNER JOIN users Users ON Users.id = Classements.user_id 
WHERE user_id in (SELECT DISTINCT EquipesUsers.user_id AS EquipesUsers__user_id 
FROM equipes_users EquipesUsers WHERE equipe_id = :c0) 
ORDER BY Classements.points desc, Classements.participations asc

这个没问题(没有()):

SELECT Classements.classement AS Classements__classement,
Classements.points AS Classements__points, 
Classements.participations AS Classements__participations, 
RANK() over (order by points desc)cl_rank, 
Users.id AS Users__id, 
Users.user_login AS Users__user_login, 
Users.picture AS Users__picture 
FROM classements Classements 
INNER JOIN users Users ON Users.id = Classements.user_id 
WHERE user_id in (SELECT DISTINCT EquipesUsers.user_id AS EquipesUsers__user_id FROM equipes_users EquipesUsers WHERE equipe_id = :c0) 
ORDER BY Classements.points desc, Classements.participations asc

任何想法删除 () ?

谢谢你的帮助

【问题讨论】:

  • 您确切的 CakePHP 版本是什么?
  • cakephp 版本:4.4.6
  • 和数据库:10.9.2-MariaDB

标签: cakephp


【解决方案1】:

开箱即用支持窗口函数(从 4.1.0 开始),它们可以通过函数生成器创建。

有一些窗口函数的简写,例如 lag()lead()rowNumber()(也许 rank() 和其他应该在其中),而其他的,基本上任何任意窗口函数都可以通过 @987654326 创建@:

->select(function (CakeORMQuery $query) {
    return [
        'classement',
        'points',
        'participations',
        'cl_rank' => $query
            ->func()
            ->aggregate('RANK')
            ->order(['points' => 'DESC'])
            ->setReturnType('integer'),
    ];
})

任何聚合函数都可以通过显式调用over()(当没有添加更多子句时创建一个空的OVER ()子句)或调用partition()order()、@987654332之一来转换为窗口函数@、rows()groups()frame()excludeCurrent()excludeGroup()excludeTies(),将隐式调用 over()

也可以看看

【讨论】:

    猜你喜欢
    • 2016-10-14
    • 1970-01-01
    • 1970-01-01
    • 2017-07-25
    • 2020-01-27
    • 1970-01-01
    • 2018-12-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多