查询生成器-组合orderby和groupby

nukf8bse  于 2021-06-21  发布在  Mysql
关注(0)|答案(3)|浏览(253)

我有一个laravel应用程序,我有一个查询,它的功能如下。

company   date      period
apple | 2017-08-23 | live
apple | 2017-09-04 | live
apple | 2014-03-04 | history
enron | 1987-09-09 | history
tesla | 2017-07-04 | live
tesla | 2017-06-03 | live

它需要按日期降序排列每个公司的条目,条件是period='live',从而返回每个公司的最后一个“live”条目。在上面的例子中,应该返回

company   date 
apple | 2017-09-04
tesla | 2017-07-04

我曾尝试使用查询生成器来完成此任务,例如:

return $query->where('period', '=', 'live')
        ->groupBy('company')
        ->orderBy('date','desc');

但是,这会首先对结果进行分组,然后对结果进行排序,从而产生不可预知的结果。根据这个问题/答案,答案在一个子查询中:
在mysql中按名称分组之前按日期和时间排序
然而,我还没能将这种方法融入到我的问题中。您能否向我解释如何有效地解决这个问题,无论是使用子查询还是使用不同的方法,但不必诉诸原始查询?

uqjltbpv

uqjltbpv1#

https://laravel.com/docs/5.5/queries#retrieving-请看这个链接。应该使用db::table('company')->where('period','live')->groupby('your condition')->orderby('your condition')->get();它将返回stdclass对象。如果需要数组,请在get()之后添加toarray();希望它能起作用,让我知道。

ebdffaop

ebdffaop2#

另一个解决办法是 groupBy() 排序后的查询结果(https://laravel.com/docs/5.5/collections#method-groupby)这完全取决于结果数据集的大小

ikfrs5lh

ikfrs5lh3#

您当前所需输出的策略是正确的,不需要子查询。以下原始mysql查询就足够了:

SELECT company, MAX(date)
FROM companies
GROUP BY company

我们可以尝试以下laravel代码:

return $query->where('period', '=', 'live')
    ->groupBy('company')
    ->orderBy('date','desc')
    ->get(['company', DB::raw('MAX(date) AS max_date')]);

与你在问题中所说的相反,如果你用 ORDER BY 如果表中的基础数据不变,那么查询结果应该是完全可复制的。
编辑:
与您的问题相反,您的注解表明您希望每个公司的每个最大日期都有完整的匹配行。如果是这样,那么您真的需要以下原始mysql查询:

SELECT c1.*
FROM companies c1
INNER JOIN
(
    SELECT company, MAX(date) AS max_date
    FROM companies
    GROUP BY company
) c2
    ON c1.company = c2.company AND
       c1.date = c2.max_date

我们可以尝试编写以下laravel代码来处理此问题:

DB::table('companies')
    ->select('*')
    ->join(DB::raw('(SELECT company, MAX(date) AS max_date
                     FROM companies GROUP BY company) c2'), function($join)
        {
            $join->on('companies.company', '=', 'c2.company');
            $join->on('companies.date', '=', 'c2.max_date');
        })
    ->orderBy('companies.date', 'DESC')
    ->get();

相关问题