繁体   English   中英

您如何使用 Laravel 基于特定列的 select distinct() 模型?

[英]How do you select distinct() models based on a specific column with Laravel?

我有一个存储文档的数据库 - 有些是彼此独立的,但有些只是以前文档的“下一个版本”。 在这种情况下,我将最新版本的 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

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

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

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

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

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

我同意 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::

暂无
暂无

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

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