Laravel选择条件加入

时间:2015-08-04 07:58:24

标签: mysql laravel join

我有3个表:Laravel 5项目中的输出,产品和服务。

我想基于这种情况在一个QUERY中加入这3个表:

如果outputs.article_type = 'p'(p = product)获取products.name

如果outputs.article_type = 's'(s = service)获取service.name

$outputs = Output::join('products', 'products.id', '=', 'outputs.article_id')
                   ... only if outputs.article_type is p (p=product)
                ->join('services', 'services.id', '=', 'outputs.article_id') 
                  ... only if outputs.article_type is s (s=service)
                ->select(array('outputs.output_at','---services or product---.name as article_name'))

2 个答案:

答案 0 :(得分:0)

不确定为什么需要将逻辑放在一个查询中。似乎是应用 KISS 的完美示例。

为什么不选择带有1个参数和普通旧IF的函数来提高可读性并使您(可能还有其他开发人员)的生活更轻松?我没有看到你正在尝试做什么的任何优势。我认为,除了简洁之外,在这种情况下,这不是最重要的因素。

在Output.php模型中:

    /**
     * Retrieves output of the given type.
     *
     * @param  string $type Type of the output
     *
     * @return mixed Object or false in case of problems
     */
    public static function getOutput($type) {

        if (!isset($type) || empty($type) || !in_array($type, ['p', 's'])) {
            // Wrong type
            return false;
        }

        if ($type === 'p') {
            $baseQuery = Output::join('products', 'products.id', '=', 'outputs.article_id');
            $table = 'products';
        } else {
            $baseQuery = Output::join('services', 'services.id', '=', 'outputs.article_id');
            $table = 'services';
        }

        return $baseQuery
                   ->select('outputs.output_at', $table.'.name as article_name')
                   ->get();
    }

然后,在控制器中

$output = Output::getOutput('p');

if ($output && count($output)) {
    // Do other stuff or pass the data to a view...
}

请记住,这没有经过测试,可能需要与我展示的略有不同的实施,但这个想法仍然很明确。

答案 1 :(得分:0)

查看A join with additional condition using Query Builder or ELoquent

但也许你应该考虑加急而不是加入?

Output::with('Product', 'Service')->....

当然你需要先添加关系

public function service() {
   if ($this->article_type == 's')
       return $this->belongsTo('Service', 'article_id', 'id')
   else
       return null;
 }

并覆盖name属性以获取所需的特定名称

public functon getNameAttribute() {
   if ($this->service)
       return $this->service->name;
   else if ($this->product)
       return $this->product->name;
}