単一のクエリでこれを行うには、おそらく SQL サブクエリを使用する必要がありますが、これは Laravel 4/5 で適切な流暢なクエリをサポートしていないようです。Eloquent オブジェクトを使用していないため、生の SQL がおそらく最も読みやすいでしょう。deals.deal_id
(以下の例では、 and列を無視することに注意してくださいmerchants.merchant_id
。これは、削除される可能性があります。代わりに、規則により、 deals.id
andフィールドのみを使用します。)merchants.id
$deals = DB::select(
DB::raw('
SELECT
deals.id AS deal_id,
deals.status,
deals.deal_text,
merchants.id AS merchant_id,
merchants.merchant_name,
merchants.about,
COALESCE(tbl_upvotes.upvotes_count, 0) AS upvotes_count,
COALESCE(tbl_downvotes.downvotes_count, 0) AS downvotes_count
FROM
deals
JOIN merchants ON (merchants.id = deals.merchant_id)
LEFT JOIN (
SELECT deal_id, count(*) AS upvotes_count
FROM tbl_deal_votes
WHERE vote = 1 && deal_id
GROUP BY deal_id
) tbl_upvotes ON (tbl_upvotes.deal_id = deals.id)
LEFT JOIN (
SELECT deal_id, count(*) AS downvotes_count
FROM tbl_deal_votes
WHERE vote = 0
GROUP BY deal_id
) tbl_downvotes ON (tbl_downvotes.deal_id = deals.id)
')
);
流暢を使用したい場合は、これでうまくいくはずです:
$upvotes_subquery = '
SELECT deal_id, count(*) AS upvotes_count
FROM tbl_deal_votes
WHERE vote = 1
GROUP BY deal_id';
$downvotes_subquery = '
SELECT deal_id, count(*) AS downvotes_count
FROM tbl_deal_votes
WHERE vote = 0
GROUP BY deal_id';
$deals = DB::table('deals')
->select([
DB::raw('deals.id AS deal_id'),
'deals.status',
'deals.deal_text',
DB::raw('merchants.id AS merchant_id'),
'merchants.merchant_name',
'merchants.about',
DB::raw('COALESCE(tbl_upvotes.upvotes_count, 0) AS upvotes_count'),
DB::raw('COALESCE(tbl_downvotes.downvotes_count, 0) AS downvotes_count')
])
->join('merchants', 'merchants.id', '=', 'deals.merchant_id')
->leftJoin(DB::raw('(' . $upvotes_subquery . ') tbl_upvotes'), function($join) {
$join->on('tbl_upvotes.deal_id', '=', 'deals.id');
})
->leftJoin(DB::raw('(' . $downvotes_subquery . ') tbl_downvotes'), function($join) {
$join->on('tbl_downvotes.deal_id', '=', 'deals.id');
})
->get();
流暢なクエリに関するいくつかの注意事項:
- DB::raw() メソッドを使用して、選択したいくつかの列の名前を変更しました。
deals.id
そうしないと、 と の間で結果に矛盾が生じていたでしょうmerchants.id
。
- COALESCE を使用して、
null
投票をデフォルトで 0 にしました。
- 読みやすくするために、サブクエリを個別の PHP 文字列に分割します。
- サブクエリに左結合を使用したため、賛成票/反対票のない取引がまだ表示されます。