如何在laravel中自我加入导致不同的值

时间:2015-06-02 03:54:57

标签: sql laravel eloquent

ID|user_id   |book_id   |author
1 |8         |7         |bill
2 |8         |6         |sally
3 |3         |7         |rob
4 |3         |4         |sarah
5 |3         |6         |jane
6 |8         |7         |frank

我想要实现的是user_id 8 book_ids与user_id 3 book_id的行匹配的行。但只选择了user_8s行。而且book_id也不同。所以我希望结果是:

第1行, 第2行

到目前为止,我有这个,但不幸的是我继续得到第6行以及第2行和第1行。基本上我希望结果与book_id不同,但我不确定如何做到这一点。

$check = DB::table('table as u1') 
->join('table as u2','u1.book_id', '=', 'u2.book_id')
->where('u2.user_id', 8)->where('u1.user_id', 3)
            ->get();

2 个答案:

答案 0 :(得分:4)

您有两种选择。您可以使用distinct()groupBy()

变式1:

$check = DB::table('table as u1')
    ->join('table as u2','u1.book_id', '=', 'u2.book_id')
    ->where('u2.user_id', 8)->where('u1.user_id', 3)
    ->distinct()
    ->get();

变式2:

$check = DB::table('table as u1')
    ->join('table as u2','u1.book_id', '=', 'u2.book_id')
    ->where('u2.user_id', 8)->where('u1.user_id', 3)
    ->groupBy('u1.book_id')
    ->get();

答案 1 :(得分:0)

正确(与其他数据库兼容并使用ONLY_FULL_GROUP_BY启用,默认情况下在MySQL 5.7中启用)等效的MySQL查询以获得所需的结果

SELECT t.*
  FROM
(
  SELECT MIN(t1.id) id
    FROM table1 t1 JOIN table1 t2
      ON t1.book_id = t2.book_id
   WHERE t1.user_id = 8
     AND t2.user_id = 3
   GROUP BY t1.user_id, t1.book_id  
) q JOIN table1 t
    ON q.id = t.id

输出:

| ID | user_id | book_id | author |
|----|---------|---------|--------|
|  1 |       8 |       7 |   bill |
|  2 |       8 |       6 |  sally |

这是 SQLFiddle 演示

使用Laravel Query Builder,它将如下所示

$subquery = DB::table('table as t1')
    ->join('table as t2', 't1.book_id', '=', 't2.book_id')
    ->where('t1.user_id', 8)
    ->where('t2.user_id', 3)
    ->groupBy(['t1.user_id', 't1.book_id'])
    ->select(DB::raw('MIN(t1.id) as id'));
$check = DB::table('table as t')
    ->join(DB::raw("({$subquery->toSql()}) as q"), 't.id', '=', 'q.id')
    ->mergeBindings($subquery)
    ->select(['t.id', 't.user_id', 't.book_id', 't.author'])
    ->get();