I have pretty big MySQL query for performance optimization I'm adding subqueries inside a join statement. With raw SQL all working fine. Here is the query:
SELECT
campaigns.id,
campaigns.name,
CONCAT(users.id, ' ', users.email) AS usersData,
CONCAT(campaigns.cpm, ' ', currencies.currency_code) AS cpm,
CONCAT(campaign_budgets.total_spend, ' ', currencies.currency_code) AS total_spend,
creatives.impressionsCount,
creatives.bidsCount,
creatives.winsAmount,
creatives.winsPercentage,
creatives.creativeIds
FROM campaigns
INNER JOIN users ON campaigns.user_id = users.id
INNER JOIN campaign_budgets ON campaigns.id = campaign_budgets.campaign_id
INNER JOIN currencies ON campaigns.currency_type_id = currencies.id
LEFT JOIN (
SELECT
GROUP_CONCAT(creatives.id) as creativeIds,
creatives.campaign_id,
creatives.user_id,
impressions.impressionsCount,
bids.bidsCount,
bids.winsAmount,
bids.winsPercentage
from creatives
LEFT JOIN (
SELECT
count(impressions.id) as impressionsCount,
impressions.user_id,
impressions.creative_id
from impressions
GROUP BY impressions.user_id
) as impressions ON creatives.user_id = impressions.user_id
LEFT JOIN (
SELECT
count(bids.id) as bidsCount,
SUM(CASE WHEN bids.status = 'won' THEN 1 ELSE 0 END) AS winsAmount,
SUM(CASE WHEN bids.status = 'won' THEN 1 ELSE 0 END) / COUNT(bids.id) * 100 AS winsPercentage,
bids.user_id,
bids.creative_id
from bids
GROUP BY bids.user_id
) as bids ON creatives.user_id = bids.user_id
GROUP BY creatives.campaign_id
) as creatives ON campaigns.id = creatives.campaign_id
GROUP BY campaigns.id
and I need convert it to Doctrine DQL somehow if is it possible. I've faced an issue when adding a subquery to join statement. Here is my code:
$columns = [
'campaign.id',
'campaign.name',
'CONCAT(owner.id,\' \', owner.email) as ownerEmail',
'CONCAT(campaign.cpm,\' \', currency.currencyCode) as cpm',
'CONCAT(budget.totalSpend,\' \', currency.currencyCode) as totalSpend',
'COUNT(imp.id) as impressionsCount',
'COUNT(bid.id) as totalBidsCount',
'SUM(case when bid.status = \'won\' then 1 else 0 end) as winsAmount',
'SUM(case when bid.status = \'won\' then 1 else 0 end)/COUNT(bid.id)*100 as winsPercentage',
];
$bids = $this->_em->getRepository(Bid::class)
->createQueryBuilder('bids')
->select([
'count(bids.id) as bidsCount',
'SUM(CASE WHEN bids.status = \'won\' THEN 1 ELSE 0 END) AS winsAmount',
'SUM(CASE WHEN bids.status = \'won\' THEN 1 ELSE 0 END) / COUNT(bids.id) * 100 AS winsPercentage',
'bids.userId',
'bids.creativeId'
])->getDQL();
$impressions = $this->_em->getRepository(Impression::class)
->createQueryBuilder('imp')
->select([
'count(imp.id) as impressionsCount',
'imp.userId',
'imp.creativeId'
])->getDQL();
$creative = $this->_em->getRepository(Creative::class) ->createQueryBuilder('cr')->select('cr.id')
->select([
'GROUP_CONCAT(cr.id) as creativeIds',
'cr.campaignId',
'cr.userId',
'impressions.impressionsCount',
'bids.bidsCount',
'bids.winsAmount',
'bids.winsPercentage'
])
->leftJoin(Impression::class, sprintf('(%s) as imp', $impressions), Expr\Join::WITH, 'imp.id = cr.userId')
->leftJoin(Bid::class, sprintf('(%s) as bid', $bids), Expr\Join::WITH, 'bids.id = cr.userId')
->getDQL();
$query = $this->createQueryBuilder('campaign')
->select($columns);
$query
->join('campaign.user', 'owner')
->join('campaign.campaignBudget', 'budget')
->join('campaign.currencyType', 'currency')
->leftJoin(Creative::class, sprintf('(%s) as creative', $creative), Expr\Join::WITH, 'campaign.id = cr.campaignId');
$query->groupBy('campaign.id');
$query->setMaxResults($limit);
$query->setFirstResult($offset);
return $query->getQuery()->useQueryCache(true)->getResult();
I'm getting the error [Syntax Error] line 0, col 626: Error: Expected Doctrine\ORM\Query\Lexer::T_IDENTIFIER, got '('
, issue is in adding subquery to join statement.
I would appreciate any help!!