与Laravel 5雄辩的CONCAT专栏

时间:2017-03-11 12:14:43

标签: php mysql laravel-5

将我视为laravel初学者

目标是:我有两个列,现在我需要id以表格中同一行的component name作为前缀。

例如(工作)......我有像

这样的Mysql
SELECT CONCAT(components.name," ", components.id) AS ID
FROM   `components` 

输出

  

ID

|TestComp 40  |
 -------------
|component 41 |
 -------------
|test 42      |

我需要用laravel雄辩的方式,因为这里的Component是模型名称。所以我尝试了像

这样的东西
$comp=Component::select("CONCAT('name','id') AS ID")->get()

但它不起作用 我认为因为语法错误 请帮助我正确的语法。使用laravel Models

注意:我做了上面的查询,将其称为互联网上可用的查询。

User::select(DB::raw('CONCAT(last_name, first_name) AS full_name'))

5 个答案:

答案 0 :(得分:29)

您需要将查询包装在DB::raw

$comp = Component::select(DB::raw("CONCAT('name','id') AS ID"))->get()

另外,请注意,因为您正在执行此类查询,您的模型可能会有不同的行为,因为此选择会从select语句中删除所有其他字段。 因此,如果没有新查询,则无法从模型中读取其他字段。所以只能用它来读取数据而不是修改数据。

另外,为了使它成为一个好的列表,我建议你将查询修改为:

$comp = Component::select(DB::raw("CONCAT('name','id') AS display_name"),'id')->get()->pluck('display_name','id');
// dump output to see how it looks.
dd($comp);// array key should be the arrray index, the value the concatted value.

答案 1 :(得分:3)

我自己来这个帖子寻求答案。对我来说唯一的问题是答案对我的情况并不适用。我有许多表关系设置,我需要其中一个子对象具有连接字段。 DB::raw解决方案对我来说太乱了。我一直在寻找并找到了我需要的答案,觉得这是一个更容易的解决方案。

我会建议尝试Eloquent Accessor,而不是DB::raw。访问器允许您检索模型属性并创建不是由原始模型创建的新属性。

例如,假设我有一个基本的USER_PROFILE表。它包含id, first_name, last_name。我需要CONCAT两个名称属性来返回其用户的全名。在我创建的php artisan make:model UserProfile的USER_PROFILE模型中,我将放置以下内容:

class UserProfile extends Model
{

  /**
   * Get the user's full concatenated name.
   * -- Must postfix the word 'Attribute' to the function name
   *
   * @return string
   */

  public function getFullnameAttribute()
  {
      return "{$this->first_name} {$this->last_name}";
  }

}

从这里,当我进行任何雄辩的调用时,我现在可以访问该附加属性访问器。

| id | first_name | last_name |
-------------------------------
| 1  | John       | Doe       |


$user = App\UserProfile::first(); 

$user->first_name;   /** John **/
$user->fullname;    /** John Doe **/

我会说我确实碰到了一个问题。那就是尝试创建一个具有相同名称的修改属性,就像你的例子(id,ID)一样。我可以修改id值本身,但因为我声明了相同的名称,它似乎只允许访问该字段值而没有其他字段。

其他人说他们可以做到,但我无法解决这个问题的确切问题。

答案 2 :(得分:3)

我正在研究posgresql和mysql:

DB::raw('CONCAT(member.last_name, \' \', member.first_name) as full_name')

答案 3 :(得分:3)

这是Laravel中列串联的示例。

我需要按名称搜索用户,并且用户名有三列(name_first,name_middle,name_last),因此我在Laravel UserModel中创建了一个范围,该范围采用 $ query 和< strong>用户名作为第二个参数。

public function scopeFindUserByName($query,$name) {
    // Concat the name columns and then apply search query on full name
    $query->where(DB::raw(
            // REPLACE will remove the double white space with single (As defined)
            "REPLACE(
                /* CONCAT will concat the columns with defined separator */
                CONCAT(
                    /* COALESCE operator will handle NUll values as defined value. */
                    COALESCE(name_first,''),' ',
                    COALESCE(name_middle,''),' ',
                    COALESCE(name_last,'')
                ),
            '  ',' ')"
        ),
    'like', '%' . $name . '%');
}

,您可以在需要按用户名搜索用户的任何地方使用此范围,例如

UserModel::findUserByName("Max Begueny");

OR

$query = UserModel::query();
$query->findUserByName("Max Begueny");

要检查此SQL查询的结果,只需阅读本文即可。 https://stackoverflow.com/a/62296860/11834856

答案 4 :(得分:0)

清理数据:在使用Laravel之前和现在,当使用其他语言进行开发时,我会定期使用CONCAT()。这里的答案在一定程度上可行,但是在Laravel / Eloquent / Query Builder中仍然没有一种使用CONCAT()的优雅方法 我发现的。

但是,我发现在返回结果之后对cols进行连接对我来说效果很好,并且通常非常快-清理数据-(除非您有巨大的结果可能出于性能目的而应该“分块”)。

foreach($resultsArray AS $row){
    $row['fullname'] = trim($row['firstname']).' '.trim($row['lastname']);
}

这当然是一个折衷,但是就我个人而言,我发现它更易于管理,并且不限制我对Eloquent的使用以及查询生成器的使用。 (以上是伪代码-未经测试,请根据需要进行调整)

还有其他解决方法,不与Eloquent / Query Builder功能混淆,例如在表中创建串联的col,在这种情况下为full_name-在插入/更新记录时保存全名。这并不罕见。