【问题标题】:How do you select distinct() models based on a specific column with Laravel?你如何使用 Laravel 基于特定列选择 distinct() 模型?
【发布时间】:2019-10-13 17:35:20
【问题描述】:

我有一个用于存储文档的数据库——有些是相互独立的,但有些只是之前文档的“下一个版本”。在这种情况下,我将最新版本的 id 存储在一个列中。

示例数据集如下所示:

id | name       | version | validated | latest_version_id
 1 | 'Doc 1'    |       1 |      true | null
 2 | 'Doc 2'    |       1 |      true | null
 3 | 'Doc 3 v1' |       1 |      true |    5
 4 | 'Doc 3 v2' |       2 |      true |    5
 5 | 'Doc 3 v3' |       3 |     false |    5

我希望能够选择所有已验证 文档的最新 版本。通常是返回数据集中第 1、2 和 4 行的请求。

我希望能够像Docs::where('validated', true)->distinct('latest_version_id')->get() 这样的东西,但显然不是那么简单..

任何查询大师指出我正确的方向?一种解决方案是获取所有结果,然后过滤掉一些模型,但这听起来不是很优化。

【问题讨论】:

标签: php mysql laravel laravel-5 eloquent


【解决方案1】:

我认为您会遇到麻烦,因为没有唯一的方法(我可以看到)来识别一个文档与另一个文档相关。 IE。 Doc 3 v1Doc 3 v2 是同一文档对人类...但是应用程序如何知道这一点?它如何搜索以了解哪些是常见的,从而检查该特定文档的最新版本?

我认为您最好的解决方案可能是,如果您可以稍微重新构建您存储数据的方式,为一组文档提供可能的 FK,您就可以解决这个问题。这样,“文档表”将允许查询具体知道哪些文档是相同的。然后,除了现有的 name 列之外,您上面的现有表将具有 FK doc_id。因此,您消除了各种名称的问题(它们都将由 FK 附加到同一个主文档)。这将允许您显示哪个版本对应于该特定主文档以及该版本属于哪个集合,然后您可以根据这些参数更轻松地管理查询。

【讨论】:

  • 谢谢 - 我不确定我是否理解使用 FK 来识别“文档集”与将“文档集”识别为具有相同行的当前架构之间的区别'latest_version_id'。你介意详细说明一下吗?
  • 当然。我可以看到您使用latest_version_id 的去向,这对于一张非常小的桌子来说是有意义的。但是,它使查询更加复杂,因为您必须查找 null 并尝试将表连接到自身(循环)上才能找到哪个文档适合哪个版本集。如果您有一个用于文档的专用表,并且上面的 this 现有表用于已验证/附加到这些 FK 的版本,那么您的查询可以更简单并直接提取您的want,即为经过验证的人找到最新版本的文档集。
【解决方案2】:

我同意 Watercayman,您应该考虑重构。在短期内,您可以使用以下方法,但它不是 100% 可靠的,但它会通过您当前的数据集实现您想要的效果

  $unversioned = Doc::query()->whereNull('latest_version_id')->where('validated', true);
  $versioned = DB::table(DB::raw("(SELECT * 
                                   FROM docs WHERE latest_version_id IS NOT NULL AND validated = true 
                                   ORDER BY version DESC) as t"))
                            ->groupBy('latest_version_id');

  $unversioned->union($versioned)->get();

请注意模型应该是单数的——这就是为什么我叫 Doc:: 而不是 Docs::

【讨论】:

  • +1 来自我。复杂任务的良好解决方案。但我认为,由于架构过于复杂,拥有latest_version_id 的通知很快就会给他带来麻烦。
  • 我同意它应该重新架构。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-11
  • 2019-06-15
  • 2018-01-28
  • 2017-10-08
  • 2019-10-26
  • 1970-01-01
相关资源
最近更新 更多