【问题标题】:Convert raw SQL to Laravel Query Builder将原始 SQL 转换为 Laravel 查询构建器
【发布时间】:2021-08-19 12:29:30
【问题描述】:

我在将此 SQL 查询转换为 Laravel 查询构建器时遇到了困难。我尝试了几个小时,但无法解决这个问题。我尝试了将 SQL 转换为查询构建器的在线工具,但没有奏效。

这是我的代码:

SELECT 
   technologies.name_en,
   Count(cig_members.id) AS CigTotal,
   Count(CASE
           WHEN cig_members.is_ethnic = 1 THEN 1
           ELSE NULL
         END) AS CigTotalEthnic,
   Count(CASE
           WHEN cig_members.gender = 'female' THEN 1
           ELSE NULL
         END) AS CigTotalFemale,
   Count(CASE
           WHEN cig_members.gender = 'female'
                AND cig_members.is_ethnic = 1 THEN 1
           ELSE NULL
         END) AS CigTotalEthnicFemale,
   Count(farmers.id) AS NonCigTotal,
   Count(CASE
           WHEN farmers.is_ethnic = 1 THEN 1
           ELSE NULL
         END) AS NonCigtoTalEthnic,
   Count(CASE
           WHEN farmers.gender = 'female' THEN 1
           ELSE NULL
         END) AS NonCigTotalFemale,
   Count(CASE
           WHEN farmers.gender = 'female'
                AND farmers.is_ethnic = 1 THEN 1
           ELSE NULL
         END) AS NonCigtTotalEthnicFemale
   FROM   adopting_technologies
   JOIN adopting_farmers
          ON adopting_farmers.id = adopting_technologies.adopting_farmer_id
   LEFT JOIN cig_members
          ON cig_members.id = adopting_farmers.cig_member_id
   LEFT JOIN farmers
          ON farmers.id = adopting_farmers.farmer_id
   LEFT JOIN financial_years
          ON financial_years.id = adopting_farmers.financial_year_id
   LEFT JOIN technologies
          ON technologies.id = adopting_technologies.technology_id
   GROUP  BY adopting_technologies.technology_id

如何转换?

【问题讨论】:

  • 您是否已有adopting_technologies 的模型?还是想使用通用 ORM?
  • @RobBiermann 我为“adopting_technologies”建模

标签: php sql laravel laravel-query-builder


【解决方案1】:
DB::table('adopting_technologies')
            ->select('adopting_technologies.technology_id', 'technologies.name_en')
            ->selectRaw("
                COUNT(cig_members.id) AS CigTotal,
                COUNT(CASE WHEN cig_members.is_ethnic = 1 THEN 1 ELSE NULL END) AS CigTotalEthnic,
                COUNT(CASE WHEN cig_members.gender = 'female' THEN 1 ELSE NULL END) AS CigTotalFemale,
                COUNT(CASE WHEN cig_members.gender = 'female' AND cig_members.is_ethnic = 1 THEN 1 ELSE NULL END) AS CigTotalEthnicFemale,
                COUNT(farmers.id) AS NonCigTotal,
                COUNT(CASE WHEN farmers.is_ethnic = 1 THEN 1 ELSE NULL END) AS NonCigtoTalEthnic,
                COUNT(CASE WHEN farmers.gender = 'female' THEN 1 ELSE NULL END) AS NonCigTotalFemale,
                COUNT(CASE WHEN farmers.gender = 'female' AND farmers.is_ethnic = 1 THEN 1 ELSE NULL END) AS NonCigtTotalEthnicFemale
            ")
            ->join('adopting_farmers', 'adopting_farmers.id', '=', 'adopting_technologies.adopting_farmer_id')
            ->leftJoin('cig_members', 'cig_members.id', '=', 'adopting_farmers.cig_member_id')
            ->leftJoin('farmers', 'farmers.id', '=', 'adopting_farmers.farmer_id')
            ->leftJoin('financial_years', 'financial_years.id', '=', 'adopting_farmers.financial_year_id')
            ->leftJoin('technologies', 'technologies.id', '=', 'adopting_technologies.technology_id')
            ->groupBy('adopting_technologies.technology_id')
            ->get();

【讨论】:

  • 你使用了错误的连接,所以这会破坏结果
  • @RobBiermann 抱歉,忽略了这一点。更新的答案。
  • 而且用户说他有模型,所以需要使用ORM :)
  • @RobBiermann 请参阅下面的答案以了解 Eloquent 方法。
【解决方案2】:
class adopting_technologies extends Model
{
    public function newCollection(array $models = [])
    {
        return new FarmerCollection($models);
    }
    public function adopting_farmers()
    {
        return $this->belongsTo(adopting_farmers::class);
    }
    // other relations for 'cig_members', 'farmers', 'financial_years' and 'technologies'
}
namespace App\Collections;

use Illuminate\Database\Eloquent\Collection;
 
class FarmerCollection extends Collection
{

    public function cigTotal()
    {
        return $this->pluck('cig_members')->map(function($items) { return $items->count(); })->sum();
    }
    // other totals for cigTotalEthnic, CigTotalFemale, CigTotalEthnicFemale, NonCigTotal, NonCigtoTalEthnic, NonCigTotalFemale, NonCigtTotalEthnicFemale
}

【讨论】:

    【解决方案3】:

    大致应该是这样的:

    $result = AdoptingTechnology::selectRaw("
            technologies.name_en,
       Count(cig_members.id) AS CigTotal,
       Count(CASE
               WHEN cig_members.is_ethnic = 1 THEN 1
               ELSE NULL
             END) AS CigTotalEthnic,
       Count(CASE
               WHEN cig_members.gender = 'female' THEN 1
               ELSE NULL
             END) AS CigTotalFemale,
       Count(CASE
               WHEN cig_members.gender = 'female'
                    AND cig_members.is_ethnic = 1 THEN 1
               ELSE NULL
             END) AS CigTotalEthnicFemale,
       Count(farmers.id) AS NonCigTotal,
       Count(CASE
               WHEN farmers.is_ethnic = 1 THEN 1
               ELSE NULL
             END) AS NonCigtoTalEthnic,
       Count(CASE
               WHEN farmers.gender = 'female' THEN 1
               ELSE NULL
             END) AS NonCigTotalFemale,
       Count(CASE
               WHEN farmers.gender = 'female'
                    AND farmers.is_ethnic = 1 THEN 1
               ELSE NULL
             END) AS NonCigtTotalEthnicFemale
             ")
                ->join('adopting_farmers', 'adopting_farmers.id','adopting_technologies.adopting_farmer_id')
                ->leftJoin('cig_members','cig_members.id','adopting_farmers.cig_member_id')
                ->leftJoin('farmers','farmers.id','adopting_farmers.farmer_id')
                ->leftJoin('financial_years','financial_years.id','adopting_farmers.financial_year_id')
                ->leftJoin('technologies','technologies.id','adopting_technologies.technology_id')
                ->groupBy('adopting_technologies.technology_id')
                ->get();
    

    如果您有任何问题,请告诉我:) ofc 无法在本地测试

    【讨论】:

      猜你喜欢
      • 2020-10-19
      • 2020-02-07
      • 1970-01-01
      • 1970-01-01
      • 2019-02-03
      • 2019-05-31
      • 2023-01-14
      • 2015-06-26
      • 2017-01-05
      相关资源
      最近更新 更多