【问题标题】:SQL Query Builder - Grouping and Ordering (Laravel)SQL 查询生成器 - 分组和排序 (Laravel)
【发布时间】:2019-01-17 11:32:56
【问题描述】:

我需要从我的一个表中获取一组结果以输出到图表。该图表需要显示“本学年(2018 年 9 月 1 日至 2018 年 8 月 31 日)每个月的关注数量”。

返回的结果应该类似于:

| month     | total |
|-----------|-------|
| September | 15    |
| October   | 23    |
| December  | 24    |
| January   | 438   |

当我尝试将月份组合在一起时,问题就出现了;我得到一个不正确的计数值。

我目前的查询是:-

    // Returns 2018-09-01 00:00:00
        $start = Carbon::createMidnightDate(Carbon::now()->subMonths(8)->year, 9, 1);
    // Gets current date
        $end = Carbon::now();

        $concerns = DB::table('concerns')
            ->select(DB::raw('MONTHNAME(created_at) as month, count(*) as total, created_at'))
            ->whereBetween('created_at', [$start, $end])
            ->groupBy('month')
            ->groupBy('created_at')
            ->orderBy('created_at', 'asc')
            ->get()->mapWithKeys(function ($item) {
                return [$item->month => $item->total];
          });

但是这会返回我:-

| month     | total |
|-----------|-------|
| September | 1     |
| October   | 1     |
| December  | 1     |
| January   | 1     |

由于created_at 日期的分组,显然没有将所有单独的值加在一起,但是由于 MySQL only_full_group_by 模式,排除它会阻止我订购它。

任何建议将不胜感激!

【问题讨论】:

    标签: mysql laravel group-by sql-order-by


    【解决方案1】:

    我认为您不需要 created_at 在您的 SELECT 中获得您想要的结果。您应该能够将查询简化为:

    $concerns = DB::table('concerns')
        ->select(DB::raw('MONTHNAME(created_at) as month, count(*) as total'))
        ->whereBetween('created_at', [$start, $end])
        ->groupBy('month')
        ->orderBy('created_at', 'asc')
    

    请注意,这假设$start$end 之间的间隔为12 个月或更短。否则,您还需要按YEAR(created_at) 分组。

    如果您正在运行 MySQL 8,或者启用了only_full_group_by,您将需要付出更多努力才能获得有效查询以满足GROUP BY 的要求。这应该有效:

    $concerns = DB::table('concerns')
        ->select(DB::raw('MONTHNAME(created_at) AS month, YEAR(created_at) AS year, count(*) as total'))
        ->whereBetween('created_at', [$start, $end])
        ->groupBy('year', 'month')
        ->orderBy('year', 'asc')
        ->orderByRaw("MONTH(STR_TO_DATE(CONCAT('1 ', month, ' ', year), '%e %M %y')) asc")
    

    我已经对 dbfiddle 上的查询进行了演示

    【讨论】:

    • 不错的一个。是否有任何理由拥有 2 个 orderBy 而不是单个 orderBy('created_at', 'asc')
    • @Mozammil 即使created_at 是每个组的任意值,它也会随着每个月的增加而增加。
    • 不幸的是,我无法让第二个的 CONCAT() 位正常工作 - PHPStorm 只是将其突出显示为语法错误,但看不出原因
    • 抱歉,忘记添加我试过 orderByRaw() - 它是这样的:link
    • @NickDavies 看我的编辑,orderByRaw 只有一个参数,你需要像我一样将asc 组合成字符串
    猜你喜欢
    • 2019-09-12
    • 1970-01-01
    • 1970-01-01
    • 2016-09-26
    • 2018-08-30
    • 2021-07-04
    • 2021-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多