简体   繁体   English

MySQL返回2个链接项,按创建顺序排序并按表ID分组

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

Been trying to think up the best way to do this but so far I have been stumped. 一直在尝试思考实现此目的的最佳方法,但到目前为止,我一直很困惑。

Basically in 1 query I want to get data from 2 tables but limit them in an unorthodox way. 基本上在1个查询中,我想从2个表中获取数据,但以非正统的方式限制它们。

table1 is a parent of table2 . table1table2的父级。 I need 2 table2 rows returned for every 1 table1 row. 我需要为每1个table1行返回2个table2行。

So in data it looks like this: 所以在数据中看起来像这样:

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

But the actual mysql data is something like this: 但是实际的mysql数据是这样的:

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

This is easy enough if there is no limitation on how much items per table1 row there are, but I need to limit them to 2, order the items by the created date, and group them by the table1 id. 如果不限制每个table1行中有多少个项目,这很容易,但是我需要将它们限制为2个,按创建日期对项目进行排序,并按table1 id对它们进行分组。

I am using Laravel for this, but I know this is a situation where DB:raw is used, here is the concept of what I got. 我为此使用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');

I am thinking do a raw join and try to do a table subquery for it to return 2 of every table1 item but never had to try to create duplicate items deliberately before and I feel it would be totally the wrong way to go about it. 我正在考虑做一个原始联接,并尝试对其执行一个表子查询,以返回每个table1项的2个,但是从来没有尝试过故意故意创建重复项,我觉得这样做是完全错误的。

Anyone got any thoughts on this? 有人对此有任何想法吗?

Oh and also to explain why I am not using a model for this. 哦,还要解释为什么我不为此使用模型。 Currently this works using normal Eloquent models, however Eloquent does multiple queries and processes the data on the php side, this specific query churns out ALOT of data, so in order to keep it efficient I want to try to do it all in 1 query (and its hitting php max execution time). 目前,这可以使用普通的Eloquent模型工作,但是Eloquent会执行多个查询并在php端处理数据,该特定查询会产生大量数据,因此为了保持效率,我想尝试在1个查询中全部完成(及其达到php的最大执行时间)。

Here is a sample of the eventual output 这是最终输出的示例

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

So the "sub items" are basically logs, they track "work" done to the item, I need to the get the current and the previous one for reports, however using the test data I have right now that is about 20,001 queries in 1 page load. 因此,“子项目”基本上是日志,它们跟踪对该项目完成的“工作”,我需要获取当前的和上一个报告,但是使用我现在拥有的测试数据(约1笔,约20001笔)页面加载。

So this solution I attempted is very improper. 因此,我尝试的此解决方案是非常不正确的。 I do not believe you are using queries the way they were designed and that is what the biggest problem is. 我不相信您使用查询的方式来设计查询,这就是最大的问题。 You should consider tracking this data differently than what is currently being tracked. 您应该考虑与当前跟踪的数据不同地跟踪此数据。

I would do something along the lines of the updated_at being the most recent update to the element. 我将按照updated_at作为元素的最新更新来进行操作。 I would then have a history table that would only record the previous most item according to the id. 然后,我将有一个历史记录表,该表仅根据ID记录前一个项目。 If you needed to save more data than that then it would most likely be ok to continue to inputing data into this history, but then you would only ever need to pull the most recent id. 如果您需要保存更多数据,则可以继续向该历史记录中输入数据,但是您只需要提取最新的ID。 Understandably you have a large set of predefined data, but if you can change it this is the route I would seriously consider. 可以理解,您有大量的预定义数据,但是如果可以更改它,这就是我会认真考虑的方法。

Problems that I do not see a solution to are: 我看不到解决方案的问题是:

  • The inability to limit the query in a way to get only 2 rows defined by X while until X ends as we talked about can be done in PHP so it seems to work! 无法限制查询的方式只能获得X定义的2行,而直到我们所说的 X结束时,可以在PHP中完成,所以它似乎可以工作!
  • Inefficiency is very likely to occur. 低效率很可能发生。 apparently expected 显然是预期的
  • \n
  • Lost logic. 失去逻辑。 (not 100% sure why you started off this way) (不确定100%为什么要以这种方式开始)

I wish I could help more, but I can't think of a solution within the parameters of SQL or an efficient loop in PHP to keep the structure you have defined and get the correct results. 我希望我能提供更多帮助,但是我想不出SQL参数中的解决方案 或PHP中的有效循环 来保持定义的结构并获得正确的结果。

If using PHP the loop will not be that efficient, but it will be right. 如果使用PHP,则循环效率不高,但这是正确的。 You found a solution that works well for your standards. 您找到了一种适合您的标准的解决方案。

\n

 
 
 
  
  $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')) ...
 
  

I don't have the opportunity to try this, but can you use this raw query in your execution and see if it does the correct thing. 我没有机会尝试此操作,但是您可以在执行过程中使用此原始查询,看看它是否执行正确的操作。 This should cover it, but I do believe you are right that a regular Query Build will not do this correctly. 这应该涵盖了它,但是我相信您是对的,常规的查询构建将无法正确执行此操作。

I have been playing around in HeidiSQL to get a query that works, this seems to get close enough that I can use. 我一直在HeidiSQL中玩耍以获取有效的查询,这似乎已经足够我可以使用了。

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

It does not limit to 2, but is simple enough that it should run quickly. 它不限于2,但足够简单,应该可以快速运行。

Originally I had a sub query, but I realized that there was no need for it if I remove the thought of limiting the joined tables results. 最初,我有一个子查询,但是我意识到,如果我消除了限制联接表结果的想法,则不需要它。

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

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