【问题标题】:SQL Query with JOIN, WHERE and AND clause to convert in Laravel queries使用 JOIN、WHERE 和 AND 子句在 Laravel 查询中转换的 SQL 查询
【发布时间】:2017-06-06 19:33:25
【问题描述】:

我在将我的 SQL 查询转换为 laravel 查询时遇到问题。我想加入两个表usersmessages,这样我就可以获得与其他用户对话的用户。

数据库结构:

用户:

消息:

这是我得到我想要的东西的 SQL 查询:

SELECT u.id, c.id, u.first_name, u.last_name FROM messages c, users u 
      WHERE (CASE WHEN c.user_one =  @USERID THEN c.user_two = u.ID WHEN c.user_two = @USERID THEN c.user_one= u.id END ) 
      AND ( c.user_one = @USERID OR c.user_two = @USERID ) Order by c.id DESC Limit 20

这是我的 Laravel 查询:

DB::table('messages')
   ->join('users', function($join) use ($user_id) {
        $join->select(DB::raw('CASE WHEN messages.user_one = ' . $user_id . ' THEN messages.user_two = ' . $user_id . 'WHEN messages.user_two = ' . $user_id . ' THEN messages.user_one = ' . $user_id));
        $join->on(function($query) use ($user_id)
        {
             $query->where('messages.user_one', '=', $user_id);
             $query->orWhere('messages.user_two', '=',$user_id);
        });       
   })
   ->select('users.*', 'messages.*')
   ->get();

【问题讨论】:

  • @userid 是在哪里定义的?
  • “与其他用户有对话的用户”是什么意思?您希望所有用户都在列 user_one 或 user_two 中的消息表中?
  • @Strawberry 它作为参数传递,function getMessage($user_id)@Autista_z 换句话说,我只想显示当前用户的所有对话。

标签: mysql laravel laravel-5.4


【解决方案1】:

更新: 抱歉,我最初的答案不是以安全的方式注入变量。请使用它在原始查询中安全地注入变量。

原始语句中的 SQL 注入安全性。

在原始查询中,我们需要记住将所有变量传递给我们的 mysql 使用提供的第二个参数的数据库。

在您的情况下,您只需将问号占位符放置在要注入变量的位置,然后将变量按照与占位符相同的顺序放入第二个参数数组中。

来源:http://s4.jeffsbio.co.uk/laravel-5-query-builder-where-raw-2

更新的查询:-

DB::table('messages as m')
        ->join('users as u',function($join){
            $join->on('u.id','=','m.user_one')
            ->orOn('u.id','=','m.user_two'); 
        })
        ->where(function($query) use($user_id){
            $query->where('m.user_one','=',$user_id);
            $query->orWhere('m.user_two','=',$user_id);
        })
       ->where(function($query) use($user_id){
            $query->whereRaw(
                        'CASE WHEN m.user_one = ?'.
                        ' THEN m.user_two = u.id'. 
                        ' WHEN m.user_two = ?'.
                        ' THEN m.user_one = u.id END',[$user_id,$user_id]);
                    //here we passed the variables in exact order of their usage in query
       })
      ->select('u.id as user_id', 'm.id as messages_id','u.first_name','u.last_name')
      ->orderBy('m.id','DESC')
      ->limit('20')
      ->get(

原答案: 你不能像你一样在join子句中使用select子句。

使用这个:-

DB::table('messages as m')
->join('users as u',function($join){
     $join->on('u.id','=','m.user_one')
     ->orOn('u.id','=','m.user_two'); 
})
->where(function($query) use($user_id){
    $query->where('m.user_one','=',$user_id);
    $query->orWhere('m.user_two','=',$user_id);
})
->where(function($query) use($user_id){
    $query->whereRaw(DB::raw(
           'CASE WHEN m.user_one = '.$user_id.
           ' THEN m.user_two = u.id'. 
           ' WHEN m.user_two = '.$user_id.
           ' THEN m.user_one = u.id END'));
   })
->select('u.id as user_id', 'm.id as messages_id','u.first_name','u.last_name')
 ->orderBy('m.id','DESC')
 ->limit('20')
 ->get();

【讨论】:

  • 谢谢。有用。我只是好奇使用DB::raw时的注入点,这样注入user_id是否安全?
  • @JAlc 感谢您指出您的意见,我没有以安全的方式注入变量。我已经更新了我的答案,请看一下。
  • 非常感谢您。 :)
猜你喜欢
  • 2017-12-21
  • 2014-08-23
  • 1970-01-01
  • 2021-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多