繁体   English   中英

在Laravel中,当orderBy()处理关系时如何合并where()和orderBy()?

[英]In Laravel, how to combine where() and orderBy() when orderBy() is working on relationship?

我有两个模型,一个Track模型和一个Artist模型,其中每个Track模型belongsTo()一个Artist模型。 Track模型有一个number列,而Artist模型有一个name列。 我想检索number = 1所有Tracks ,然后显示按其艺术家姓名排序的Tracks 到目前为止,我只想出了如何做一个或另一个,而不是两个都做。

我希望能够通过以下方式做到这一点:

Track::with(['artist' => function($q) {
            $q->orderBy('name');
        }])->where('number', 1)->get();

这将显示number = 1所有轨道,但不会以任何特定顺序对tracks进行排序。 如果完全删除with()我将得到相同的结果。 相反,如果删除where()子句,则会在数据库中获得所有轨道,并按艺术家的名称对其进行排序。 如何结合这两个功能? 结果应如下所示:

[
  {
    "id": 17,
    "created_at": "2019-09-04 22:33:50",
    "updated_at": "2019-09-04 22:33:50",
    "number": 1,
    "title": "Iste omnis maxime inventore rerum nam et.",
    "artist_id": 2,
    "album_id": 4,
    "length": "06:08",
    "disc_number": 1,
    "artist": {
      "id": 2,
      "created_at": "2019-09-04 22:33:46",
      "updated_at": "2019-09-04 22:33:49",
      "name": "Ace",
      "image_id": "4"
    }
  },
  {
    "id": 35,
    "created_at": "2019-09-04 22:33:54",
    "updated_at": "2019-09-04 22:33:54",
    "number": 1,
    "title": "Doloremque quidem voluptatibus doloribus et.",
    "artist_id": 4,
    "album_id": 7,
    "length": "18:13",
    "disc_number": 3,
    "artist": {
      "id": 4,
      "created_at": "2019-09-04 22:33:46",
      "updated_at": "2019-09-04 22:33:53",
      "name": "Bar",
      "image_id": "10"
    }
  },
  {
    "id": 54,
    "created_at": "2019-09-04 23:00:08",
    "updated_at": "2019-09-04 23:00:08",
    "number": 1,
    "title": "Ut placeat assumenda aut.",
    "artist_id": 21,
    "album_id": 17,
    "length": "09:25",
    "disc_number": 4,
    "artist": {
      "id": 21,
      "created_at": "2019-09-04 23:00:08",
      "updated_at": "2019-09-04 23:00:08",
      "name": "Cat",
      "image_id": "22"
    }
  },
  {
    "id": 71,
    "created_at": "2019-09-04 23:00:11",
    "updated_at": "2019-09-04 23:00:11",
    "number": 1,
    "title": "Omnis et dolores odio a eius.",
    "artist_id": 22,
    "album_id": 20,
    "length": "16:48",
    "disc_number": 2,
    "artist": {
      "id": 22,
      "created_at": "2019-09-04 23:00:08",
      "updated_at": "2019-09-04 23:00:10",
      "name": "Dog",
      "image_id": "25"
    }
  },
]

使用这样的东西:

Track::with('artist')->join('artist', 'artist.id', '=', 'track.artist_id')->orderBy('artist.name', 'DESC')->get()

希望你明白我的意思

您无法使用代码按艺术家的名字进行排序,因为laravel为eager load带有曲目的艺术家,执行两个查询,您应该使用join进行一个查询,但是我给出了另外两个选项( 我不喜欢join ):

1)您可以在结果集合上使用sortBy()sortByDesc() (如果要对降序进行排序),例如:

$tracks = Track::with('artist')->where('number', 1)->get()->sortBy('artist.name');

2)您可以从Artist开始查询,但是您必须稍微更改一下视图,例如:

$artists = Artist::with(['tracks' => function($q) {
               $q->where('number', 1);
           }])->orderBy('name')->get();

3)您可以使用联接,请查看另一个答案。

仅供参考,如果您想调试查询,只需在->get()位置附加->toSql() ->get()即可获取SQL字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM