php - MYSQL/查询生成器/Eloquent - 将行转置为列

标签 php mysql laravel eloquent query-builder

** 日程安排系统(按周预约的数量):**

我希望生成一个仪表板,其中显示顾问列表以及他们在未来几周安排的预约数量。

因此,针对我的特定场景,我的 sql 查询/ Eloquent 等效查询如下:

select 
    consultant_id,
    count(appointment) as num_appointments,
    YEARWEEK(appointment, 1) as year_week 
from 
    appointments 
where 
    appointments.deleted_at is null 
    and appointments.consultant_id in (25, 29, 19, 38, 37, 32, 14, 21, 12, 40) 
    and appointment > '2014-12-07 16:39:07' 
    and YEARWEEK(now(), 1) + 4 >= YEARWEEK(appointment, 1) 
group by consultant_id, YEARWEEK(appointment, 1) 
order by consultant_id, YEARWEEK(appointment, 1) asc;


    $consultants = $this->consultant
        ->with(['appointments' => function($q) {
            $q->scheduled()
                ->where(\DB::raw('YEARWEEK(now(), 1) + 4'), '>=', \DB::raw('YEARWEEK(appointment, 1)'))
                ->select([
                    'consultant_id',
                    \DB::raw('count(appointment) as num_appointments'),
                    \DB::raw('YEARWEEK(appointment, 1) as year_week'),
                ])
                ->groupBy(\DB::raw('consultant_id, YEARWEEK(appointment, 1)'))
                ->orderBy(\DB::raw('consultant_id, YEARWEEK(appointment, 1)', 'DESC'));
        }])
        ->orderBy('name')
        ->paginate(10);

这适用于每位顾问,如果有预约,它将提供如下信息:

consultant_id   num_appointments    year_week
14                      5            201450
14                      3            201451
29                      4            201450
29                      1            201451
40                      1            201450
40                      1            201452

但是,如果没有约会,则year_week 将丢失。

因此,在 mysql 中,然后在 Laravel 的查询生成器中,我希望能够将 year_week 行转置为列。这样表就会输出:

consultant_id    week0     week1    week2
consultant_id   201450    201451    201452
14                 5         3         NULL
29                 4         1         NULL
40                 1         NULL      1

更新

SELECT
  consultant_id,
  COUNT(CASE WHEN YEARWEEK(DATE_ADD(now(), INTERVAL 0 WEEK), 1) = YEARWEEK(appointment, 1) THEN 1 END) as this_week,
  COUNT(CASE WHEN YEARWEEK(DATE_ADD(now(), INTERVAL 1 WEEK), 1) = YEARWEEK(appointmnet, 1) THEN 1 END) as week1,
  COUNT(CASE WHEN YEARWEEK(DATE_ADD(now(), INTERVAL 2 WEEK), 1) = YEARWEEK(appointmnet, 1) THEN 1 END) as week2
FROM
  demand as d
WHERE date_created >= DATE_SUB(CURDATE(), INTERVAL 3 MONTH)
GROUP BY consultant_id;

最佳答案

解决方案 1:在 spatie macro collection 中使用转置

转置的目标是旋转多维数组,将行变成列,将列变成行。

collect([
    ['Jane', 'Bob', 'Mary'],
    ['<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="177d76797257726f767a677b723974787a" rel="noreferrer noopener nofollow">[email protected]</a>', '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="61030e03210419000c110d044f020e0c" rel="noreferrer noopener nofollow">[email protected]</a>', '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="acc1cdded5ecc9d4cdc1dcc0c982cfc3c1" rel="noreferrer noopener nofollow">[email protected]</a>'],
    ['Doctor', 'Plumber', 'Dentist'],
]
)->transpose()->toArray();

// [
//     ['Jane', '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2a404b444f6a4f524b475a464f04494547" rel="noreferrer noopener nofollow">[email protected]</a>', 'Doctor'],
//     ['Bob', '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="fe9c919cbe9b869f938e929bd09d9193" rel="noreferrer noopener nofollow">[email protected]</a>', 'Plumber'],
//     ['Mary', '<a href="https://stackoverflow.com/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="2944485b50694c51484459454c074a4644" rel="noreferrer noopener nofollow">[email protected]</a>', 'Dentist'],
// ]

解决方案 2:使用 group by in collection groupBy 方法按给定键对集合的项目进行分组:

$collection = collect([
    ['account_id' => 'account-x10', 'product' => 'Chair'],
    ['account_id' => 'account-x10', 'product' => 'Bookcase'],
    ['account_id' => 'account-x11', 'product' => 'Desk'],
]);

$grouped = $collection->groupBy('account_id');

$grouped->toArray();

/*
    [
        'account-x10' => [
            ['account_id' => 'account-x10', 'product' => 'Chair'],
            ['account_id' => 'account-x10', 'product' => 'Bookcase'],
        ],
        'account-x11' => [
            ['account_id' => 'account-x11', 'product' => 'Desk'],
        ],
    ]
*/

关于php - MYSQL/查询生成器/Eloquent - 将行转置为列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27348304/

相关文章:

mysql - 为我的 SQL Server 声明并设置无法识别的语法

php - 在没有 aJax 的情况下在 Laravel 中使用 DataTables - 表中没有可用数据

php - 如何使用 ffmpeg 获取视频长度

javascript - 同一页面中有多个计数器来统计每个用户的时间。

php - Laravel 5 关于共享主机的问题

mysql - 如何检查两个不同表中是否存在两列数据? MySQL

php - Laravel Cache 不在生产服务器上存储缓存文件

php - 创建正则表达式以匹配 00 :00:00 for duration (not time) 的格式

php - ui slider 上的值

php - 根据选择的下拉菜单自动填充,需要帮助