Mysql返回2个链接项,按表id创建和分组排序


Mysql return 2 linked items, ordered by created and grouped by table id

一直在努力想出最好的方法来做到这一点,但到目前为止,我一直被难住了。

基本上在一个查询中,我想从两个表中获取数据,但以一种非正统的方式限制它们。

table1table2的父级。我需要为每1行table1返回2行table2

在data中是这样的

Row 1
  Item 1
  Item 2
Row 2
  Item 1
  Item 2 

实际的mysql数据是这样的:

Row 1 Item 1
Row 1 Item 2
Row 2 Item 1
Row 2 Item 2

如果对每个table1行有多少项没有限制,这很容易,但我需要将它们限制为2,按创建的日期排序,并按table1 id分组。

我正在使用Laravel,但我知道这是使用DB:raw的情况,这是我得到的概念。

$data = DB::table('table2')
    ->select('table2.data', 'table2.created_at')
    ->leftJoin('table1', 'table2.part_id', '=', 'table1.id')
    ->orderBy('table2.created_at')
    ->groupBy('table1.id');

我正在考虑做一个原始连接,并尝试为它做一个表子查询,以返回每个table1项目中的2个,但从来没有试图故意创建重复的项目,我觉得这将是完全错误的方式去做它。

有人对此有什么想法吗?

哦,也解释了为什么我没有使用模型。目前这工作使用正常的Eloquent模型,然而Eloquent在php端做多个查询和处理数据,这个特定的查询产生了大量的数据,所以为了保持它的效率,我想尝试在一个查询中完成这一切(并且它达到php最大执行时间)。

下面是最终输出的示例

Item 1 
  previous (created at) - data
  current (created_at) - data
Item 2
  previous (created at) - data
  current (created_at) - data

所以"子项目"基本上是日志,他们跟踪"工作"完成的项目,我需要得到当前和前一个报告,但是使用测试数据,我现在有大约200,001查询在1页加载。

所以我尝试的这个解决方案是非常不合适的。我不相信你使用查询的方式,他们的设计,这是最大的问题所在。您应该考虑以不同于当前正在跟踪的方式跟踪此数据。

我会按照updated_at作为元素的最新更新来做一些事情。然后,我将拥有一个历史表,该表只根据id记录之前的最项。如果您需要保存更多的数据,那么很可能可以继续将数据输入到该历史记录中,但是您只需要提取最近的id。可以理解的是,您有大量预定义的数据集,但如果您可以更改它,这是我会认真考虑的路线。

我看不到解决方案的问题是:

  • 无法限制查询在某种程度上只能得到X定义的2行,而直到X结束,正如我们所讨论的,可以在PHP中完成,所以它似乎是有效的!
  • 效率低下很可能发生。<<strong>显然预期/strong><罢工>
  • 失去逻辑。(不是100%确定为什么你这样开始)

我希望我能帮助更多,但我不能想到SQL或PHP 中有效循环的参数内的解决方案,以保持您已定义的结构并获得正确的结果。

如果使用PHP,循环将不是那么有效,但它将是正确的。你找到了一个适合你的标准的解决方案。

<罢工>

$data = DB::table('table2')
    ->select(DB::raw('SELECT table2.data,table2.created_at FROM table2 WHERE table2.part_id=table1.id ORDER BY table2.created_at DESC LIMIT 2'))
    ...

我没有机会尝试这个,但是你可以在你的执行中使用这个原始查询,看看它是否做正确的事情。这应该涵盖它,但我相信你是对的,一个常规的查询构建将不会正确地做到这一点。

我一直在HeidiSQL中玩,以获得一个有效的查询,这似乎足够接近,我可以使用。

select 
    distinct `table2`.`created_at`, 
    `table2`.`points`,
    `table1`.`id`
from `table2`
inner join `table1`
on ( `table1`.`id` = `table2`.`part_id` )

它不限制为2,但足够简单,应该运行得很快。

最初我有一个子查询,但我意识到,如果我消除了限制连接表结果的想法,就不需要它了。