Laravel Eloquent选择每个分组的第一行

4

我在SQLite数据库中有subjects表和tutorials表。我想选择当前教程。以下是我的表格:

  • Subjects table:

    -------------------
    |  id |   name    |
    -------------------
    |  1  | Chemistry |
    |  2  | Physic    |
    -------------------
    
  • Tutorials table:

    -----------------------------------------
    | id  |    name   | subj_id | completed |
    -----------------------------------------
    |  1  | chapter 1 |   1     |     1     |
    |  2  | chapter 2 |   1     |     0     |
    |  3  | chapter 3 |   1     |     0     |
    |  4  | chapter 1 |   2     |     1     |
    |  5  | chapter 2 |   2     |     1     |
    |  6  | chapter 3 |   2     |     0     |
    |  7  | chapter 4 |   2     |     0     |
    -----------------------------------------
    

我的当前 eloquent 是:

  $query->where('completed', false)->groupBy('subj_id')->get();

它返回以下内容:
-----------------------------------------
| id  |    name   | subj_id | completed |
-----------------------------------------
|  3  | chapter 3 |   1     |     0     |
|  7  | chapter 4 |   2     |     0     |
-----------------------------------------

现在我希望选择id为2和6。
-----------------------------------------
| id  |    name   | subj_id | completed |
-----------------------------------------
|  2  | chapter 2 |   1     |     0     |
|  6  | chapter 3 |   2     |     0     |
-----------------------------------------

如何使用sqlite获取id为2和6的数据?


你选择2和6而不是3和7的逻辑是什么? - lukasgeiter
嗨,Lukas。简单来说,ID 2 是化学的第二章,ID 3 是化学的第三章。ID 1 已完成。因此,我希望能够获取当前的化学教程章节以及物理学科的相同内容。 - Ryan Exlay
3个回答

7

在@zerofl4g的帮助下,我的问题已得到解决。

@zerofl4g的热心帮助解决了这个难题。

$query->select(DB::raw("SELECT MIN(id), name, subj_id FROM tutorials
 WHERE completed = 0 GROUP BY subj_id"));

对我来说它不起作用,但是它帮了我很多。我不知道为什么它对我没有起作用,但我认为我将其用作子查询。因此,我得到了重复的选择和from错误。对于想要将其用作单个查询的人,它肯定会起作用。

我的解决方案只是使用DB :: raw选择列,并且-> from('tutorials')也是可选的,因为它是长查询的子查询。

$query->select(DB::raw('MIN(id) as id, name, subj_id'))->from('tutorials')
->where('completed', false)->groupBy('subj_id');

我使用的最终 eloquent 是

$query->select(DB::raw('MIN(id) as id, name, subj_id'))
->where('completed', false)->groupBy('subj_id');`

希望能有所帮助。

4
如果您想要在分组后返回第一行,可以尝试下面的代码。我认为您想得到的是未完成学科中最新的章节。
$data = Tutorial::where('completed', 0)->get();
$groups = $data->groupBy('subj_id');

$results = [];
foreach($groups as $group) {
    $results[] = head($group);
}
return $results;
  1. 获取所有教程行

  2. 然后,按subj_id进行分组。您得到的数据如下所示

{
    1: [{
        id: "2",
        name: "chapter 2",
        subj_id: "1",
        completed: "0"
    }, {
        id: "3",
        name: "chapter 3",
        subj_id: "1",
        completed: "0"
    }],

    2: [{
        id: "6",
        name: "chapter 3",
        subj_id: "2",
        completed: "0"
    }, {
        id: "7",
        name: "chapter 4",
        subj_id: "2",
        completed: "0"
    }]
}

使用laravel中的head()辅助函数,遍历每个组并获取最小id。

嗨,zer0fl4g,谢谢你的回答。我的查询只是长查询的子查询。我不能使用foreach或任何php函数。如果我运行这个查询select min(id), name, subj_id from tutorials where completed = 0 group by subj_id,我会得到id为2和6的结果。但问题是我不知道如何将该查询作为子查询运行。无论如何感谢你的帮助和支持。 - Ryan Exlay
我制作了易于理解的小表格。`$members = Member :: has('lotteries') - > with([ 'lotteries' => function($ query){ $query- > select(array('lotteries.id','lotteries.name','basic_amt','lotteries.total_amt')); }, 'lotteries.prizes' => function($ query){ $query
  • select(array('prizes.id','prizes.lottery_id','prizes.prize_number','prizes.current_amt'))
  • where('completed',false)
  • groupBy('lottery_id'); } ] - > get(array('members.id','members.name')) - > toJSON(); //$members = Member :: all(array('id','name')) - > toJSON(); 返回$members;`
- Ryan Exlay
我所描述的部分是 $query ->select(array('prizes.id','prizes.lottery_id','prizes.prize_number','prizes.current_amt')) ->where('completed', false) ->groupBy('lottery_id'); - Ryan Exlay
嗨,Zer0fl4g,我遇到了这个错误。因为有两个“select”语句,导致出现以下错误信息:"SQLSTATE[HY000]: General error: 1 near "SELECT": syntax error (SQL: select SELECT MIN(id),` 谢谢你的帮助,兄弟。我已经尝试过了,并且在你建议之后再次尝试,但是仍然出现相同的错误。 - Ryan Exlay
嗨zerofl4g,感谢你的帮助。我的问题没有被Laravel解决,但是当我在SQLite查询运行时,我可以得到我想要的结果。但正如我在评论中所说,我无法以Laravel的方式编写该查询。 :-( 抱歉,我写的是SQL查询而不是Laravel Eloquent。 :-( - Ryan Exlay
显示剩余6条评论

0

正确的查询应该是这样的

$query->where('completed', false)->get()->groupBy('subj_id');

get() 将在 groupBy 之前首先被调用。我的意思是,一旦 get() 创建了集合,您可以使用所有集合方法。要了解更多细节并了解所有集合方法,请查看 https://laravel.com/docs/5.8/collections#method-groupby


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接