获取 groupBy 中的最后一项

Posted

技术标签:

【中文标题】获取 groupBy 中的最后一项【英文标题】:Getting last item in groupBy 【发布时间】:2018-05-17 15:20:22 【问题描述】:

我在这里找到了一些我遵循的答案,发现它在本地工作,所以我推到我们的测试框,我发现这个特定的数据库查询通过进入 mysql 和 @987654321 持续超过 1300 秒@它挂在copying to tmp table

它是 Laravel 4.2,相当古老的遗留代码,我只是想在开发更高版本时稳定它。下面的代码根据 api_call 大约每 30 秒重复一次,这一切都很好,除了它没有完成并收到 504 Gateway Time-out 我觉得我正在做一些递归的事情,或者在这里搜索一个非常大的数据库会是一个问题吗?

我想要做的只是运行一个 groupBy,但不是按第一个分组,而是按最后一个分组,以防其他详细信息被更新。

我们将非常感谢您提供的任何帮助。

public function api_prevnames()

    if (Auth::user()->repeat_vistor == 'Y') 
        $names = DB::table('visitors')
            ->select(DB::raw('first_name,last_name,email,car_reg,OPTIN,vistor_company'))
            ->where('user_id', Auth::user()->id)
            ->where('hidden', 0)
            ->where('email', '<>', '')
            ->whereRaw('id IN (select MAX(id) FROM visitors GROUP BY first_name, last_name, email)')
            ->get();
    

    return JSONResponseGenerator::successResponse($names->toArray());


生成此查询

select first_name,last_name,email,car_reg,OPTIN,vistor_company from `visitors` where `user_id` = '439' and `hidden` = '0' and `email` <> '' and id IN (select MAX(id) FROM visitors GROUP BY first_name, last_name, email)

之前的代码运行不到几秒钟,我在下面添加了这些代码:

            $names = DB::table('visitors')
            ->select(DB::raw('first_name,last_name,email,car_reg,OPTIN,vistor_company'))
            ->where('user_id', Auth::user()->id)
            ->where('hidden', 0)
            ->where('email', '<>', '')
            ->groupBy('first_name', 'last_name', 'email')
            ->get();

【问题讨论】:

【参考方案1】:

您可以尝试运行以下命令:

SELECT
    first_name,
    last_name,
    email,
    car_reg,
    OPTIN,
    vistor_company
FROM (
    SELECT
        MAX(id) AS id
    FROM `visitors`
    WHERE
        `user_id` = 439
        AND `hidden` = 0
        AND `email` <> ''
    GROUP BY
        first_name,
        last_name,
        email
) AS subQ
NATURAL JOIN `visitors`;

加入通常比其他方式更快,但我认为这不会有帮助,因为您显然没有按索引分组。为此,您必须更改结构,我强烈建议您这样做。尽量减少 first_name、last_name 和 email 的最大长度,这样就可以创建这三者的组合索引。如果您可以在不杀死一半系统的情况下更改数据库结构本身,则应考虑规范化该表,例如有一个带有访问者的表和另一个带有这些访问者访问的表(与外键的关系),因此您可以按键分组由三个长度很大的未索引字符串分组。

【讨论】:

Here is an imgur of the table/query上面的文字查询我也加了。 绝对粉碎它的伙伴,完全符合我的需要,而且速度也很快! 我已经更新了您的编辑,以添加我在 Laravel 中修复此问题的确切过程。非常感谢您的帮助。

以上是关于获取 groupBy 中的最后一项的主要内容,如果未能解决你的问题,请参考以下文章

获取 groupby 中的第一个和最后一个值

Mongoose 查询 - groupBy 类别并获取每个类别的最后 4 项

pandas使用groupby.first函数groupby.nth函数获取每个组中的第一个值实战:groupby.first函数和groupby.nth函数对比(对待NaN的差异)

从groupby中的列获取模式[重复]

pandas使用groupby函数基于指定分组变量对dataframe数据进行分组使用last函数获取每个分组数据中每个分组的最后一个样本数据

从 laravel 中的 groupBy 获取行 ID