Laravel 运行 不禁用 mysql 严格模式的复杂查询
Laravel run complex query without disabling mysql strict mode
我有一个相当复杂的查询,例如:
SELECT
COALESCE (
SUM (
CASE WHEN `closed_job_reports`.`job_report_id` IS NOT NULL THEN 1 ELSE 0 END
),
0
) AS `CLOSED`,
COALESCE (
SUM (
CASE WHEN `job_reports`.`id` IS NULL
AND `jobs`.`deadline` <= CURRENT_TIMESTAMP() THEN 1 ELSE 0 END
),
0
) AS `OVERDUE`,
COALESCE (
SUM (
CASE WHEN (
`assigned_jobs`.`assigned_job_id` IS NULL
AND `pending_jobs`.`id` IS NOT NULL
AND `jobs`.`deadline` > NOW ()
)
OR (
`assigned_jobs`.`assigned_job_id` IS NOT NULL
AND `jobs`.`deadline` > NOW ()
AND `job_reports`.`id` IS NULL
) THEN 1 ELSE 0 END
),
0
) AS `PENDING`,
COALESCE (
SUM (
CASE WHEN `closed_job_reports`.`job_report_id` IS NULL
AND `job_reports`.`id` IS NOT NULL THEN 1 ELSE 0 END
),
0
) AS `AWAITING_CLOSURE`,
COALESCE (
SUM (
CASE WHEN (
`job_reports`.`id` IS NULL
OR `assigned_jobs`.`assigned_job_id` IS NULL
)
AND (
`jobs`.`deadline` > NOW ()
) THEN 1 ELSE 0 END
),
0
) AS `OPEN`,
COALESCE (
COUNT (*),
0
) AS `TOTAL`,
COALESCE (
SUM (
`job_reports`.`distance_travelled`
),
0
) AS `distance_travelled`,
COALESCE (
ROUND(
SUM (
CASE WHEN (
`job_reports`.`id` IS NOT NULL
AND `jobs`.`job_category_id` = 2
) THEN ABS (
TIMESTAMPDIFF (
SECOND, `job_reports`.`end_time`,
`job_reports`.`start_time`
)
) ELSE 0 END
) / 3600,
2
),
0
) AS `hours_worked`,
COALESCE (
COUNT (`job_reports`.`id`),
0
) AS `num_reported_sites`,
COALESCE (
SUM (
CASE WHEN `jobs`.`job_category_id` = 2
AND `job_reports`.`id` IS NOT NULL THEN 1 ELSE 0 END
),
0
) AS `pm_num_reported_jobs`,
COALESCE (
SUM (
CASE WHEN `jobs`.`job_category_id` = 2 THEN 1 ELSE 0 END
),
0
) AS `pm_num_jobs`
FROM
`jobs`
INNER JOIN `job_categories` ON `job_categories`.`id` = `jobs`.`job_category_id`
LEFT OUTER JOIN `assigned_jobs` ON `jobs`.`id` = `assigned_jobs`.`job_id`
LEFT OUTER JOIN `job_reports` ON `assigned_jobs`.`assigned_job_id` = `job_reports`.`assigned_job_id`
LEFT OUTER JOIN `closed_job_reports` ON `job_reports`.`id` = `closed_job_reports`.`job_report_id`
LEFT OUTER JOIN `pending_jobs` ON `jobs`.`id` = `pending_jobs`.`new_job_id`
WHERE
`jobs`.`date_added` BETWEEN '2022-01-01' AND '2022-02-17'
-- GROUP BY
-- `closed_job_reports`.`job_report_id`, `job_reports`.`id`, `assigned_jobs`.`assigned_job_id`, `pending_jobs`.`id`, `closed_job_reports`.`job_report_id`, `job_reports`.`id`, `assigned_jobs`.`assigned_job_id`
ORDER BY
`jobs`.`id` DESC
我可以很容易地从 PhpMyAdmin 运行 它得到我想要的,如下所示:
但是当使用 DB::select 方法从 laravel 宁 运行 时,我得到一个语法错误:
SQLSTATE[42000]: Syntax error or access violation: 1140 Mixing of
GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is
illegal if there is no GROUP BY clause (SQL: SELECT
...
我有很多这样的疑问,我会 运行宁。我检查了这个 post:
Syntax error or access violation: 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...)
但我的似乎有点复杂,因为我必须从几个相关表中进行查询。我看到其他人建议禁用mysql严格模式,但我不想那样做。
我知道你们中的一些人可能遇到过复杂查询的这个问题。请问您在解决其中一些问题时使用了哪些步骤或技术?谢谢。
好的。所以你有一个像我一样非常复杂的查询?好吧,我发现我不需要数据库中的视图,因为在我的情况下它是不必要的。
首先,我必须将查询分解为更小的部分,一次一个。这是在我被指向 Laravel 文档 https://laravel.com/docs/9.x/queries#raw-expressions
之后
我从原始查询的主要 table - 工作开始,然后继续将联接添加到查询中。
数据分组是最复杂的部分。那就是我遇到的问题。因此,在分解查询之后,我不得不更改我用于原始数据分组的内容。将数据分组到工作类别名称(或工作类别 ID)中使其更简单。
最后,我得到的显示结果看起来好多了。
这里用一段代码来说明。
我对原始查询进行了一些修改,但仍保留我需要的连接。
$users = DB::table('jobs')
->select(DB::raw(
'job_categories.category_name, COUNT(jobs.id) as jobs_count, COUNT(assigned_jobs.assigned_job_id) AS assigned_jobs_count,
COUNT(recurring_jobs.job_id) AS recurring_jobs_count,
COALESCE(SUM(
CASE WHEN
assigned_jobs.assigned_job_id IS NULL
THEN 1 ELSE 0
END
), 0) AS unassigned_jobs_count,
COUNT(job_reports.id) AS reported_jobs_count,
COALESCE(SUM(
CASE WHEN job_reports.id IS NULL
THEN 1 ELSE 0
END
), 0) AS unreported_jobs_count,
COALESCE(SUM(
CASE WHEN closed_job_reports.job_report_id IS NOT NULL THEN 1 ELSE 0
END
), 0) AS closed_jobs_count,
COALESCE(SUM(
CASE WHEN job_reports.id IS NOT NULL AND closed_job_reports.job_report_id IS NULL THEN 1 ELSE 0
END
), 0) AS reported_unclosed_jobs_count,
COALESCE(SUM(
CASE WHEN
(job_reports.id IS NULL AND jobs.deadline > NOW() AND assigned_jobs.assigned_job_id IS NULL)
THEN 1 ELSE 0
END
), 0) AS opened_only_jobs_count,
COALESCE(SUM(
CASE WHEN
job_reports.id IS NULL AND jobs.deadline > NOW() AND assigned_jobs.assigned_job_id IS NOT NULL OR
(job_reports.id IS NULL AND jobs.deadline > NOW() AND pending_jobs.id IS NOT NULL)
THEN 1 ELSE 0
END
),0) AS pending_jobs_count,
COALESCE(SUM(
CASE WHEN job_reports.id IS NULL AND jobs.deadline <= NOW() THEN 1 ELSE 0
END
), 0) AS overdue_jobs_count
'
))
->groupBy('job_categories.category_name')
->join('job_categories', 'job_categories.id', '=', 'jobs.job_category_id')
->leftJoin('assigned_jobs', 'jobs.id', '=', 'assigned_jobs.job_id')
->leftJoin('pending_jobs', 'jobs.id', '=', 'pending_jobs.new_job_id')
->leftJoin('job_reports', 'job_reports.assigned_job_id', '=', 'assigned_jobs.assigned_job_id')
->leftJoin('closed_job_reports', 'closed_job_reports.job_report_id', '=', 'job_reports.id')
->leftJoin('recurring_jobs', 'recurring_jobs.job_id', '=', 'jobs.id')
->get();
我希望这可以帮助人们解决他们的错误问题
SQLSTATE[42000]:语法错误或访问冲突:1140 如果没有 GROUP BY,则混合使用没有 GROUP 列的 GROUP 列(MIN()、MAX()、COUNT(),...)是非法的子句
当使用 laravel 或其他类似框架时...
我有一个相当复杂的查询,例如:
SELECT
COALESCE (
SUM (
CASE WHEN `closed_job_reports`.`job_report_id` IS NOT NULL THEN 1 ELSE 0 END
),
0
) AS `CLOSED`,
COALESCE (
SUM (
CASE WHEN `job_reports`.`id` IS NULL
AND `jobs`.`deadline` <= CURRENT_TIMESTAMP() THEN 1 ELSE 0 END
),
0
) AS `OVERDUE`,
COALESCE (
SUM (
CASE WHEN (
`assigned_jobs`.`assigned_job_id` IS NULL
AND `pending_jobs`.`id` IS NOT NULL
AND `jobs`.`deadline` > NOW ()
)
OR (
`assigned_jobs`.`assigned_job_id` IS NOT NULL
AND `jobs`.`deadline` > NOW ()
AND `job_reports`.`id` IS NULL
) THEN 1 ELSE 0 END
),
0
) AS `PENDING`,
COALESCE (
SUM (
CASE WHEN `closed_job_reports`.`job_report_id` IS NULL
AND `job_reports`.`id` IS NOT NULL THEN 1 ELSE 0 END
),
0
) AS `AWAITING_CLOSURE`,
COALESCE (
SUM (
CASE WHEN (
`job_reports`.`id` IS NULL
OR `assigned_jobs`.`assigned_job_id` IS NULL
)
AND (
`jobs`.`deadline` > NOW ()
) THEN 1 ELSE 0 END
),
0
) AS `OPEN`,
COALESCE (
COUNT (*),
0
) AS `TOTAL`,
COALESCE (
SUM (
`job_reports`.`distance_travelled`
),
0
) AS `distance_travelled`,
COALESCE (
ROUND(
SUM (
CASE WHEN (
`job_reports`.`id` IS NOT NULL
AND `jobs`.`job_category_id` = 2
) THEN ABS (
TIMESTAMPDIFF (
SECOND, `job_reports`.`end_time`,
`job_reports`.`start_time`
)
) ELSE 0 END
) / 3600,
2
),
0
) AS `hours_worked`,
COALESCE (
COUNT (`job_reports`.`id`),
0
) AS `num_reported_sites`,
COALESCE (
SUM (
CASE WHEN `jobs`.`job_category_id` = 2
AND `job_reports`.`id` IS NOT NULL THEN 1 ELSE 0 END
),
0
) AS `pm_num_reported_jobs`,
COALESCE (
SUM (
CASE WHEN `jobs`.`job_category_id` = 2 THEN 1 ELSE 0 END
),
0
) AS `pm_num_jobs`
FROM
`jobs`
INNER JOIN `job_categories` ON `job_categories`.`id` = `jobs`.`job_category_id`
LEFT OUTER JOIN `assigned_jobs` ON `jobs`.`id` = `assigned_jobs`.`job_id`
LEFT OUTER JOIN `job_reports` ON `assigned_jobs`.`assigned_job_id` = `job_reports`.`assigned_job_id`
LEFT OUTER JOIN `closed_job_reports` ON `job_reports`.`id` = `closed_job_reports`.`job_report_id`
LEFT OUTER JOIN `pending_jobs` ON `jobs`.`id` = `pending_jobs`.`new_job_id`
WHERE
`jobs`.`date_added` BETWEEN '2022-01-01' AND '2022-02-17'
-- GROUP BY
-- `closed_job_reports`.`job_report_id`, `job_reports`.`id`, `assigned_jobs`.`assigned_job_id`, `pending_jobs`.`id`, `closed_job_reports`.`job_report_id`, `job_reports`.`id`, `assigned_jobs`.`assigned_job_id`
ORDER BY
`jobs`.`id` DESC
我可以很容易地从 PhpMyAdmin 运行 它得到我想要的,如下所示:
但是当使用 DB::select 方法从 laravel 宁 运行 时,我得到一个语法错误:
SQLSTATE[42000]: Syntax error or access violation: 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...) with no GROUP columns is illegal if there is no GROUP BY clause (SQL: SELECT
...
我有很多这样的疑问,我会 运行宁。我检查了这个 post: Syntax error or access violation: 1140 Mixing of GROUP columns (MIN(),MAX(),COUNT(),...)
但我的似乎有点复杂,因为我必须从几个相关表中进行查询。我看到其他人建议禁用mysql严格模式,但我不想那样做。
我知道你们中的一些人可能遇到过复杂查询的这个问题。请问您在解决其中一些问题时使用了哪些步骤或技术?谢谢。
好的。所以你有一个像我一样非常复杂的查询?好吧,我发现我不需要数据库中的视图,因为在我的情况下它是不必要的。
首先,我必须将查询分解为更小的部分,一次一个。这是在我被指向 Laravel 文档 https://laravel.com/docs/9.x/queries#raw-expressions
之后我从原始查询的主要 table - 工作开始,然后继续将联接添加到查询中。
数据分组是最复杂的部分。那就是我遇到的问题。因此,在分解查询之后,我不得不更改我用于原始数据分组的内容。将数据分组到工作类别名称(或工作类别 ID)中使其更简单。
最后,我得到的显示结果看起来好多了。
这里用一段代码来说明。 我对原始查询进行了一些修改,但仍保留我需要的连接。
$users = DB::table('jobs')
->select(DB::raw(
'job_categories.category_name, COUNT(jobs.id) as jobs_count, COUNT(assigned_jobs.assigned_job_id) AS assigned_jobs_count,
COUNT(recurring_jobs.job_id) AS recurring_jobs_count,
COALESCE(SUM(
CASE WHEN
assigned_jobs.assigned_job_id IS NULL
THEN 1 ELSE 0
END
), 0) AS unassigned_jobs_count,
COUNT(job_reports.id) AS reported_jobs_count,
COALESCE(SUM(
CASE WHEN job_reports.id IS NULL
THEN 1 ELSE 0
END
), 0) AS unreported_jobs_count,
COALESCE(SUM(
CASE WHEN closed_job_reports.job_report_id IS NOT NULL THEN 1 ELSE 0
END
), 0) AS closed_jobs_count,
COALESCE(SUM(
CASE WHEN job_reports.id IS NOT NULL AND closed_job_reports.job_report_id IS NULL THEN 1 ELSE 0
END
), 0) AS reported_unclosed_jobs_count,
COALESCE(SUM(
CASE WHEN
(job_reports.id IS NULL AND jobs.deadline > NOW() AND assigned_jobs.assigned_job_id IS NULL)
THEN 1 ELSE 0
END
), 0) AS opened_only_jobs_count,
COALESCE(SUM(
CASE WHEN
job_reports.id IS NULL AND jobs.deadline > NOW() AND assigned_jobs.assigned_job_id IS NOT NULL OR
(job_reports.id IS NULL AND jobs.deadline > NOW() AND pending_jobs.id IS NOT NULL)
THEN 1 ELSE 0
END
),0) AS pending_jobs_count,
COALESCE(SUM(
CASE WHEN job_reports.id IS NULL AND jobs.deadline <= NOW() THEN 1 ELSE 0
END
), 0) AS overdue_jobs_count
'
))
->groupBy('job_categories.category_name')
->join('job_categories', 'job_categories.id', '=', 'jobs.job_category_id')
->leftJoin('assigned_jobs', 'jobs.id', '=', 'assigned_jobs.job_id')
->leftJoin('pending_jobs', 'jobs.id', '=', 'pending_jobs.new_job_id')
->leftJoin('job_reports', 'job_reports.assigned_job_id', '=', 'assigned_jobs.assigned_job_id')
->leftJoin('closed_job_reports', 'closed_job_reports.job_report_id', '=', 'job_reports.id')
->leftJoin('recurring_jobs', 'recurring_jobs.job_id', '=', 'jobs.id')
->get();
我希望这可以帮助人们解决他们的错误问题
SQLSTATE[42000]:语法错误或访问冲突:1140 如果没有 GROUP BY,则混合使用没有 GROUP 列的 GROUP 列(MIN()、MAX()、COUNT(),...)是非法的子句
当使用 laravel 或其他类似框架时...