= NOW()) -- only addresses that are marked matching or "to review", but before the update AND (a.refstatus LIKE '{{ matching }}' OR (a.refstatus LIKE '{{ reviewed }}' AND a.refstatuslastupdate < ar.updatedat)) AND ( a.postcode_id != ar.postcode_id OR a.street != ar.street OR a.streetnumber != ar.streetnumber OR ROUND(ST_X(a.point) * 1000000) <> ROUND(ST_X(ar.point) * 1000000) OR ROUND(ST_Y(a.point) * 1000000) <> ROUND(ST_Y(ar.point) * 1000000) ) SQL; private const SQL_MARK_MATCHING_ADDRESSES_REVIEWED_OR_TO_REVIEW = <<<'SQL' UPDATE chill_main_address a SET refstatus = '{{ matching }}', refstatuslastupdate = NOW() FROM chill_main_address_reference ar WHERE a.addressreference_id = ar.id -- restrict only on active addresses AND (a.validto IS NULL OR a.validto >= NOW()) AND a.refstatus IN ('{{ to_review }}', '{{ reviewed }}') AND a.postcode_id = ar.postcode_id AND a.street = ar.street AND a.streetnumber = ar.streetnumber AND ROUND(ST_X(a.point) * 1000000) = ROUND(ST_X(ar.point) * 1000000) AND ROUND(ST_Y(a.point) * 1000000) = ROUND(ST_Y(ar.point) * 1000000) SQL; private const SUBSTITUTES = [ '{{ to_review }}' => Address::ADDR_REFERENCE_STATUS_TO_REVIEW, '{{ matching }}' => Address::ADDR_REFERENCE_STATUS_MATCH, '{{ reviewed }}' => Address::ADDR_REFERENCE_STATUS_REVIEWED, ]; public function __construct(private Connection $connection, private LoggerInterface $logger) { } public function checkAddressesMatchingReferences(): void { $this->logger->notice(self::LOG_PREFIX.'Starting addresses matching'); $this->connection->transactional(function () { $markedAsMatching = $this->connection->executeStatement( strtr(self::SQL_MARK_MATCHING_ADDRESSES_REVIEWED_OR_TO_REVIEW, self::SUBSTITUTES) ); $markedAsToReview = $this->connection->executeStatement( strtr(self::SQL_MARK_TO_REVIEW_ADDRESS_UNMATCHING, self::SUBSTITUTES) ); $this->logger->info(self::LOG_PREFIX.'Executed address matching', [ 'marked_as_matching' => $markedAsMatching, 'marked_as_to_review' => $markedAsToReview, ]); }); } }