繁体   English   中英

如何加入多个表并分组并从一张表中获得前 2 名

[英]How to join multiple tables and group by and get top 2 from one table

我有 3 张桌子:isps、优惠和赞助商。

我有表统计信息有这 3 个表的外键。

我需要按目标、赞助商和报价对所有 isp 进行分组,但我只想获取在每个 isp、目标和赞助商中拥有最高 epc 的前 2 个报价。

Schema::create('isps', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });

Schema::create('sponsors', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });
 
Schema::create('offers', function (Blueprint $table) {
            $table->id();
            $table->string('offer_id')->nullable();
            $table->string('name');
            $table->foreignIdFor(Sponsor::class)->constrained()->cascadeOnUpdate()->cascadeOnDelete();
            $table->timestamps();
        });
 
Schema::create('statistics', function (Blueprint $table) {
            $table->id();
            $table->date('at')->nullable();
            $table->foreignIdFor(Isp::class)->nullable();
            $table->foreignIdFor(Sponsor::class)->nullable();
            $table->foreignIdFor(Offer::class)->nullable();

            $table->string('target')->default('NA');
            $table->unsignedInteger('clicks')->default(0);
            $table->unsignedDecimal('earns')->default(0);

            $table->timestamps();
        });

这是我的 function。 它可以工作,但它会获得所有优惠,而我想获得按 isps、目标、赞助商和优惠分组的顶级 epc 的前 2 个优惠。

epc=sum(statistics.earns)/ nullif(sum(statistics.clicks) group by isps, target and sponsors and offers


$stats = Statistic::query()->where('at', '>=', now()->subMonth())->selectRaw('
                 statistics.sponsor_id as sponsar_id,
                 sponsors.name as sponsor_name,
                 statistics.target,
                 statistics.isp_id as isp_id,
                 isps.name as isp_name,
                 statistics.offer_id as offer_id,
                 offers.name as offer_name, coalesce(sum(statistics.earns)/ nullif(sum(statistics.clicks)::numeric, 0),0) as epc
                ')
        ->join('sponsors', 'sponsors.id', '=', 'statistics.sponsor_id')
        ->join('offers', 'offers.id', '=', 'statistics.offer_id')
        ->join('isps', 'isps.id', '=', 'statistics.isp_id')
        ->groupBy(
            'statistics.target', 'statistics.isp_id', 'isps.name', 'statistics.sponsor_id',
            'sponsors.name', 'statistics.offer_id', 'offers.name')
        ->getQuery()
        ->get();

    if ($stats->isEmpty()) {
        return [];
    }

    return $stats->transform(fn($row) => [
        'isp' => $row->isp_name,
        'target' => $row->target,
        'sponsor' => $row->sponsor_name,
        'offer' => $row->offer_name,
        'epc' => $row->epc,
    ])->toArray();
网络服务商 目标 赞助 优惠 EPC
热信 垃圾邮件 S1 OF1 10
热信 垃圾邮件 S1 OF12 5
热信 垃圾邮件 S2 OF6 12
热信 垃圾邮件 S2 OF12 6
gmail 收件箱 S1 OF16 9
gmail 收件箱 S1 OF5 3
gmail 收件箱 S2 OF5 12
gmail 收件箱 S2 OF5 6

您可以只添加一个orderBy('')子句以按照您认为合适的方式进行排序,然后->take(2)到 select 只有两个项目

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM