我可以使用 Laravel 的查询构建器构建此查询吗?如果可以,那会是什么样子? (数据库::原始())
Can I build this query using Laravel's Query Builder and if so, what would that look like? (DB::raw())
我使用 Eloquent 和 Laravel 的查询构建器(混合)将结果查询放在一起,我想删除那个“混合”并使用 Laravel 的查询生成器。
使用 Laravel 的查询生成器,以下查询会是什么样子?
SELECT id,
name,
clicks_count,
conversions_count,
Round(((100 / clicks_count) * conversions_count), 2) AS conversion_rate,
Cast((cost_integral / clicks_count) AS UNSIGNED) AS cpc_integral,
Cast((Ifnull(revenue_integral, 0) / clicks_count) AS UNSIGNED) AS epc_integral,
Cast(Ifnull(revenue_integral, 0) AS signed) AS revenue_integral,
Cast(Ifnull(cost_integral, 0) AS UNSIGNED) AS cost_integral,
Cast((Ifnull(revenue_integral, 0) - cost_integral) AS signed) AS profit_integral,
Round((CASE
WHEN(Ifnull(revenue_integral, 0) = 0 AND Ifnull(cost_integral, 0) = 0) THEN 0
WHEN(Ifnull(revenue_integral, 0) = 0 AND Ifnull(cost_integral, 0) > 0) THEN -100
WHEN(Ifnull(revenue_integral, 0) > 0 AND Ifnull(cost_integral, 0) = 0) THEN 100
WHEN(Ifnull(revenue_integral, 0) > 0 AND Ifnull(cost_integral, 0) > 0) THEN ((revenue_integral / cost_integral) * 100)
END), 2) AS roi
FROM
(SELECT device_types.*,
(SELECT Count(clicks.id)
FROM clicks
WHERE device_types.id = clicks.device_type_id
AND clicks.created_at BETWEEN "2021-07-06 00:00:00" AND "2021-07-08 23:59:59"
AND clicks.campaign_id = 2) AS clicks_count,
(SELECT Count(conversions.id)
FROM conversions
INNER JOIN clicks ON clicks.id = conversions.click_id
WHERE device_types.id = clicks.device_type_id
AND conversions.created_at BETWEEN "2021-07-06 00:00:00" AND "2021-07-08 23:59:59"
AND clicks.campaign_id = 2) AS conversions_count,
(SELECT sum(clicks.cost_integral)
FROM clicks
WHERE device_types.id = clicks.device_type_id
AND clicks.created_at BETWEEN "2021-07-06 00:00:00" AND "2021-07-08 23:59:59"
AND clicks.campaign_id = 2) AS cost_integral,
(SELECT sum(conversions.payout_integral)
FROM conversions
INNER JOIN clicks ON clicks.id = conversions.click_id
WHERE device_types.id = clicks.device_type_id
AND conversions.created_at BETWEEN "2021-07-06 00:00:00" AND "2021-07-08 23:59:59"
AND clicks.campaign_id = 2) AS revenue_integral
FROM device_types
INNER JOIN clicks ON clicks.device_type_id = device_types.id
WHERE clicks.campaign_id = 2
GROUP BY device_types.id) AS metrics
ORDER BY clicks_count DESC
感谢您的帮助和时间。
编辑:
一个例子就够了——不需要重建整个查询。我只 post 编辑了它,因为在上一个线程中有人告诉我 post 整个 SQL 命令而不是一小部分(否则我肯定会缩短它)。
重要的是这些“子选择”并不简单DB::raw("(SELECT COUNT(clicks.id) FROM ...
。相反,我想知道如何使用 Laravel 查询生成器来构建这些。
我就是这样做的:
use Illuminate\Database\Query\Builder;
$clicksCount = DB::table('clicks')
->whereColumn('device_types.id', 'clicks.device_type_id')
->whereBetween('clicks.created_at', [ "2021-07-06 00:00:00", "2021-07-08 23:59:59" ])
->where('clicks.campaign_id', 2)
->select(DB::raw('Count(clicks.id)');
$conversionsCount = DB::table('conversions')
->join('clicks', 'clicks.id', 'conversions.click_id')
->whereColumn('device_types.id', 'clicks.device_type_id')
->whereBetween('conversions.created_at', [ "2021-07-06 00:00:00", "2021-07-08 23:59:59" ])
->where('clicks.campaign_id', 2)
->select(DB::raw('Count(conversions.id)'));
$costIntegral = DB::table('clicks')
->whereColumn('device_types.id', 'clicks.device_type_id')
->whereBetween('clicks.created_at', [ "2021-07-06 00:00:00", "2021-07-08 23:59:59" ])
->where('clicks.campaign_id', 2)
->select(DB::raw('sum(clicks.cost_integral)'));
$revenueIntegral = DB::table('conversions')
->join('clicks', 'clicks.id', 'conversions.click_id')
->whereColumn('device_types.id', 'clicks.device_type_id')
->whereBetween('conversions.created_at', [ "2021-07-06 00:00:00", "2021-07-08 23:59:59" ])
->where('clicks.campaign_id', 2)
->select(DB::raw('sum(clicks.payout_integral)'));
$metrics = DB::table('device_types')
->join('clicks', 'clicks.device_type_id', 'device_types.id')
->where('clicks.campaign_id', 2)
->groupBy('device_types.id')
->select('device_types.*')
->selectSub($clicksCount, 'clicks_count')
->selectSub($conversionsCount, 'conversions_count')
->selectSub($costIntegral, 'cost_integral')
->selectSub($revenueIntegral, 'revenue_integral');
Builder::newQuery()->select(
'id',
'name',
'clicks_count',
'conversions_count'
)
->selectRaw('
Round(((100 / clicks_count) * conversions_count), 2) AS conversion_rate,
Cast((cost_integral / clicks_count) AS UNSIGNED) AS cpc_integral,
Cast((Ifnull(revenue_integral, 0) / clicks_count) AS UNSIGNED) AS epc_integral,
Cast(Ifnull(revenue_integral, 0) AS signed) AS revenue_integral,
Cast(Ifnull(cost_integral, 0) AS UNSIGNED) AS cost_integral,
Cast((Ifnull(revenue_integral, 0) - cost_integral) AS signed) AS profit_integral,
Round((CASE
WHEN(Ifnull(revenue_integral, 0) = 0 AND Ifnull(cost_integral, 0) = 0) THEN 0
WHEN(Ifnull(revenue_integral, 0) = 0 AND Ifnull(cost_integral, 0) > 0) THEN -100
WHEN(Ifnull(revenue_integral, 0) > 0 AND Ifnull(cost_integral, 0) = 0) THEN 100
WHEN(Ifnull(revenue_integral, 0) > 0 AND Ifnull(cost_integral, 0) > 0) THEN ((revenue_integral / cost_integral) * 100)
END), 2) AS roi')
->fromSub($metrics, 'metrics')
->orderByDesc('clicks_count')
我使用 Eloquent 和 Laravel 的查询构建器(混合)将结果查询放在一起,我想删除那个“混合”并使用 Laravel 的查询生成器。
使用 Laravel 的查询生成器,以下查询会是什么样子?
SELECT id,
name,
clicks_count,
conversions_count,
Round(((100 / clicks_count) * conversions_count), 2) AS conversion_rate,
Cast((cost_integral / clicks_count) AS UNSIGNED) AS cpc_integral,
Cast((Ifnull(revenue_integral, 0) / clicks_count) AS UNSIGNED) AS epc_integral,
Cast(Ifnull(revenue_integral, 0) AS signed) AS revenue_integral,
Cast(Ifnull(cost_integral, 0) AS UNSIGNED) AS cost_integral,
Cast((Ifnull(revenue_integral, 0) - cost_integral) AS signed) AS profit_integral,
Round((CASE
WHEN(Ifnull(revenue_integral, 0) = 0 AND Ifnull(cost_integral, 0) = 0) THEN 0
WHEN(Ifnull(revenue_integral, 0) = 0 AND Ifnull(cost_integral, 0) > 0) THEN -100
WHEN(Ifnull(revenue_integral, 0) > 0 AND Ifnull(cost_integral, 0) = 0) THEN 100
WHEN(Ifnull(revenue_integral, 0) > 0 AND Ifnull(cost_integral, 0) > 0) THEN ((revenue_integral / cost_integral) * 100)
END), 2) AS roi
FROM
(SELECT device_types.*,
(SELECT Count(clicks.id)
FROM clicks
WHERE device_types.id = clicks.device_type_id
AND clicks.created_at BETWEEN "2021-07-06 00:00:00" AND "2021-07-08 23:59:59"
AND clicks.campaign_id = 2) AS clicks_count,
(SELECT Count(conversions.id)
FROM conversions
INNER JOIN clicks ON clicks.id = conversions.click_id
WHERE device_types.id = clicks.device_type_id
AND conversions.created_at BETWEEN "2021-07-06 00:00:00" AND "2021-07-08 23:59:59"
AND clicks.campaign_id = 2) AS conversions_count,
(SELECT sum(clicks.cost_integral)
FROM clicks
WHERE device_types.id = clicks.device_type_id
AND clicks.created_at BETWEEN "2021-07-06 00:00:00" AND "2021-07-08 23:59:59"
AND clicks.campaign_id = 2) AS cost_integral,
(SELECT sum(conversions.payout_integral)
FROM conversions
INNER JOIN clicks ON clicks.id = conversions.click_id
WHERE device_types.id = clicks.device_type_id
AND conversions.created_at BETWEEN "2021-07-06 00:00:00" AND "2021-07-08 23:59:59"
AND clicks.campaign_id = 2) AS revenue_integral
FROM device_types
INNER JOIN clicks ON clicks.device_type_id = device_types.id
WHERE clicks.campaign_id = 2
GROUP BY device_types.id) AS metrics
ORDER BY clicks_count DESC
感谢您的帮助和时间。
编辑:
一个例子就够了——不需要重建整个查询。我只 post 编辑了它,因为在上一个线程中有人告诉我 post 整个 SQL 命令而不是一小部分(否则我肯定会缩短它)。
重要的是这些“子选择”并不简单DB::raw("(SELECT COUNT(clicks.id) FROM ...
。相反,我想知道如何使用 Laravel 查询生成器来构建这些。
我就是这样做的:
use Illuminate\Database\Query\Builder;
$clicksCount = DB::table('clicks')
->whereColumn('device_types.id', 'clicks.device_type_id')
->whereBetween('clicks.created_at', [ "2021-07-06 00:00:00", "2021-07-08 23:59:59" ])
->where('clicks.campaign_id', 2)
->select(DB::raw('Count(clicks.id)');
$conversionsCount = DB::table('conversions')
->join('clicks', 'clicks.id', 'conversions.click_id')
->whereColumn('device_types.id', 'clicks.device_type_id')
->whereBetween('conversions.created_at', [ "2021-07-06 00:00:00", "2021-07-08 23:59:59" ])
->where('clicks.campaign_id', 2)
->select(DB::raw('Count(conversions.id)'));
$costIntegral = DB::table('clicks')
->whereColumn('device_types.id', 'clicks.device_type_id')
->whereBetween('clicks.created_at', [ "2021-07-06 00:00:00", "2021-07-08 23:59:59" ])
->where('clicks.campaign_id', 2)
->select(DB::raw('sum(clicks.cost_integral)'));
$revenueIntegral = DB::table('conversions')
->join('clicks', 'clicks.id', 'conversions.click_id')
->whereColumn('device_types.id', 'clicks.device_type_id')
->whereBetween('conversions.created_at', [ "2021-07-06 00:00:00", "2021-07-08 23:59:59" ])
->where('clicks.campaign_id', 2)
->select(DB::raw('sum(clicks.payout_integral)'));
$metrics = DB::table('device_types')
->join('clicks', 'clicks.device_type_id', 'device_types.id')
->where('clicks.campaign_id', 2)
->groupBy('device_types.id')
->select('device_types.*')
->selectSub($clicksCount, 'clicks_count')
->selectSub($conversionsCount, 'conversions_count')
->selectSub($costIntegral, 'cost_integral')
->selectSub($revenueIntegral, 'revenue_integral');
Builder::newQuery()->select(
'id',
'name',
'clicks_count',
'conversions_count'
)
->selectRaw('
Round(((100 / clicks_count) * conversions_count), 2) AS conversion_rate,
Cast((cost_integral / clicks_count) AS UNSIGNED) AS cpc_integral,
Cast((Ifnull(revenue_integral, 0) / clicks_count) AS UNSIGNED) AS epc_integral,
Cast(Ifnull(revenue_integral, 0) AS signed) AS revenue_integral,
Cast(Ifnull(cost_integral, 0) AS UNSIGNED) AS cost_integral,
Cast((Ifnull(revenue_integral, 0) - cost_integral) AS signed) AS profit_integral,
Round((CASE
WHEN(Ifnull(revenue_integral, 0) = 0 AND Ifnull(cost_integral, 0) = 0) THEN 0
WHEN(Ifnull(revenue_integral, 0) = 0 AND Ifnull(cost_integral, 0) > 0) THEN -100
WHEN(Ifnull(revenue_integral, 0) > 0 AND Ifnull(cost_integral, 0) = 0) THEN 100
WHEN(Ifnull(revenue_integral, 0) > 0 AND Ifnull(cost_integral, 0) > 0) THEN ((revenue_integral / cost_integral) * 100)
END), 2) AS roi')
->fromSub($metrics, 'metrics')
->orderByDesc('clicks_count')