简体   繁体   English

laravel 5.3-通过whereIn mysql命令结果

[英]laravel 5.3 - order results via whereIn mysql

I have looked at most other solutions here but none of them seems to work for me. 我在这里查看了其他大多数解决方案,但似乎没有一个对我有用。 I have a table with about 100K rows in it. 我有一张约有10万行的表格。

each row is a record from an iot device, which includes the unique id of that device. 每行是来自物联网设备的记录,其中包括该设备的唯一ID。 The device id may have 10K rows from the 100K. 设备ID可能从100K开始有10K行。

Reading::whereIn('device_id', $ids)->orderBy('created_at',
 'DESC')->groupBy('device_id')->get()->

I am able to pull out the ids i need and group them together by "device_id" as query above but its picking the first result and not the last for each id. 我能够拉出我需要的ID,并通过“ device_id”将它们分组在一起,作为上面的查询,但是它为每个ID选择第一个结果而不是最后一个。

How can i get the most recent record for each id instead of the oldest? 如何获得每个ID的最新记录而不是最旧的记录?

I have looked at laravel collections and the reverse(), first(), latest(); 我看过laravel集合和reverse(),first(),latest(); option but i still cant get it 选项,但我仍然无法做到

Any ideas? 有任何想法吗?

UPDATE 更新

The best i have been able to come up with is this query below which does grab the latest record for each device_id 我能提出的最好的方法是下面的查询,它确实获取每个device_id的最新记录

SELECT t1.* FROM readings t1 WHERE t1.id = (SELECT t2.id FROM readings
t2 WHERE t2.device_id = t1.device_id ORDER BY t2.id DESC LIMIT 1)

I'll then loop through those results and grab only the records the user has access to. 然后,我将遍历这些结果,并仅获取用户有权访问的记录。

Not pretty, but it works for now. 不漂亮,但目前可以使用。

If anyone ever does find away to do it in eloquent please answer 如果有人曾经雄辩过,请回答

I believe this should work? 我相信这应该工作吗?

Reading::select('device_id', 'id', DB::raw('MAX(created_at) AS latest'))->whereIn('device_id', $ids)->orderBy('latest', 'DESC')->groupBy('device_id')->get();

Hope this helps! 希望这可以帮助!

OK, I believe this may work, as previous attempts didn't: 好的,我相信这可能会奏效,因为以前的尝试没有:

$sub = Reading::orderBy('created_at','desc');

return DB::table(DB::raw("({$sub->toSql()}) as sub"))
    ->whereIn('device_id', $ids)
    ->groupBy('device_id')
    ->get();

You basically run a 'sub query'. 您基本上运行了一个“子查询”。 So, retrieve the results in the order you need first, then run the second query to group them. 因此,按照您需要的顺序检索结果,然后运行第二个查询将它们分组。

This is kinda a tricky question to think about. 这是一个棘手的问题。 Once you re-frame the question in database lingo, something like "get max record for each id in MySQL query", it is quite easy to find a lot of SO answers. 一旦用数据库术语重新构造了问题,例如“获取MySQL查询中每个ID的最大记录”之类的东西,就很容易找到很多SO答案。

Here's a highly rated example on SO: Retrieving the last record in each group 这是关于SO的高度评价的示例: 检索每个组中的最后一条记录

In your updated query, the subquery is actually recomputed for every row I think. 在更新的查询中,实际上对我认为的每一行都重新计算了子查询。 We can do better by joining readings to itself (check above link as reference) 我们可以通过将读数与自身结合来做得更好(请查看以上链接作为参考)

SELECT r1.*
FROM readings r1
  LEFT JOIN readings r2
    ON r2.device_id = r1.device_id
       AND r1.date_created < r2.date_created
WHERE r2.device_id IS NULL # there is no row with a date_created greater than r1's
;

Indexes on device_id and date_created are an easy first step for making this faster device_id和date_created上的索引是简化此操作的第一步

I was finally able to get it sorted out. 我终于能够整理好它。 The following query returns exactly what i want in laravel. 以下查询返回的正是我想要的laravel。

$sql = Reading::select('created_at', 'column1', 'column2', 'column3', 'column4', 'column5',
'column6')->whereIn('device_id', ['0','0'])->toSql(); 

// 0 is just "empty" value, it doesn't matter here yet

$db = DB::connection()->getPdo();
$query = $db->prepare($sql);

// real ids im looking for

$query->execute(array('ffvr5g6h', 'ccvl5f4rty'));


$collection = collect($query);

// change this to take ever (n) record 

//$collection = $collection->every(100);
$collection = $collection->groupBy('device_id');

 foreach ($collection as $collect) {
                // process data
               $end = $collect->last();
               print_r($end);
            }

This query above is querying 100K rows in about half a second, then turning that into a collection for laravel, once in a collection i group by id, then grab the last record from that result. 上面的查询是在大约半秒内查询10万行,然后将其转换为laravel的集合,一次放入一个由id分组的集合中,然后从该结果中获取最后一条记录。

Thanks to all those who tried to help :) 感谢所有尝试提供帮助的人:)

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

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