Hello,
Scenario
I'm implementing a custom Filter as shown below. Here I'm using a $subQuery to retrieve the 'latest' LaserComplianceReport by accountId where the 'latest' report is determined by the createdAt field. The subquery ideally would return a single id of the `latest` LaserComplianceReport in the database. The full query then only returns LaserComplianceTasks whose LaserComplianceReportId is 'in' the result of the subquery.
Problem Description
This works fine except for the scenario when two LaserComplianceReports exists in the database with the identical createdAt. Since my database only stores createdAt down to the millisecond (ie 2024-04-25 18:42:52) it is possible that two LaserComplianceReports are created down to the same millisecond. If this occurs the subquery below returns a list of more than 1 id.
What I've Tried
I tried using select("MAXid)") instead of select("id") in the subquery but that did not appear to work to make sure it only returned 1 result. It worked sometimes and other times the filter returned 0 results.
I also tried adding ->limit(0,1) to the subquery to always limit the result to 1 in case two LaserComplianceReports had the same createdAt date but mysql doesn't allow you to add limit to a subquery...
Could someone help me adjust either my subquery or query so that only 1 LaserComplianceReportId comes back even if two reports have the same createdAt date?
Scenario
I'm implementing a custom Filter as shown below. Here I'm using a $subQuery to retrieve the 'latest' LaserComplianceReport by accountId where the 'latest' report is determined by the createdAt field. The subquery ideally would return a single id of the `latest` LaserComplianceReport in the database. The full query then only returns LaserComplianceTasks whose LaserComplianceReportId is 'in' the result of the subquery.
Problem Description
This works fine except for the scenario when two LaserComplianceReports exists in the database with the identical createdAt. Since my database only stores createdAt down to the millisecond (ie 2024-04-25 18:42:52) it is possible that two LaserComplianceReports are created down to the same millisecond. If this occurs the subquery below returns a list of more than 1 id.
What I've Tried
I tried using select("MAXid)") instead of select("id") in the subquery but that did not appear to work to make sure it only returned 1 result. It worked sometimes and other times the filter returned 0 results.
I also tried adding ->limit(0,1) to the subquery to always limit the result to 1 in case two LaserComplianceReports had the same createdAt date but mysql doesn't allow you to add limit to a subquery...
Could someone help me adjust either my subquery or query so that only 1 LaserComplianceReportId comes back even if two reports have the same createdAt date?
PHP Code:
<?php
namespace Espo\Modules\MyModule\Classes\Select\LaserComplianceTask\PrimaryFilters;
use Espo\{
Core\Select\Primary\Filter,
Modules\MyModule\Entities\LaserComplianceReport,
Modules\MyModule\Entities\LaserComplianceTask,
ORM\Query\Part\Condition as Cond,
ORM\Query\SelectBuilder as QueryBuilder
};
class Latest implements Filter
{
public function apply(QueryBuilder $queryBuilder): void
{
// a list of id's of only the most recent laser compliance reports trick to limit only 1 result
// MAX:(id) is used in case two compliance Reports have the same createdAt date
// not working on production server. need to come up with another way to limit to 1 result if same createAt
$subQuery = QueryBuilder::create()
->select("id")
->from(LaserComplianceReport::ENTITY_TYPE)
->leftJoin(LaserComplianceReport::ENTITY_TYPE, "cr2", [
"cr2.accountId:" => "accountId",
"cr2.createdAt>:" => "createdAt",
"cr2.deleted" => false,
])
->where([
"cr2.createdAt" => null,
])
->build();
$queryBuilder
->where(
Cond::in(Cond::column("laserComplianceReportId"), $subQuery)
)
->distinct();
}
}
Comment