laravel 5.3 - 通过whereIn mysql订购结果

时间:2017-01-13 20:22:18

标签: php mysql laravel

我在这里看过大多数其他解决方案,但它们似乎都不适合我。我有一张大约有100K行的表。

每一行都是来自iot设备的记录,其中包含该设备的唯一ID。设备ID可能有100K的10K行。

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

我能够将我需要的ID拉出来并通过“device_id”将它们组合在一起作为上面的查询,但是它选择了第一个结果,而不是每个id的最后一个结果。

如何获取每个ID而不是最旧的最新记录?

我查看了laravel集合和reverse(),first(),latest();选项,但我仍然无法得到它

有什么想法吗?

更新

我能想出的最好的是下面的查询,它会获取每个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)

然后我将遍历这些结果,只获取用户有权访问的记录。

不漂亮,但它现在有效。

如果有人确实找到了雄辩的话,请回答

4 个答案:

答案 0 :(得分:0)

我相信这应该有用吗?

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

希望这有帮助!

答案 1 :(得分:0)

好的,我相信这可行,因为以前的尝试并没有:

ws:\\localhost\

您基本上运行了一个'子查询'。因此,首先按照您需要的顺序检索结果,然后运行第二个查询对它们进行分组。

答案 2 :(得分:0)

这是一个值得思考的棘手问题。一旦你在数据库术语中重新构建了问题,就像在"获取MySQL查询中每个id的最大记录一样,很容易找到很多SO答案。

这是SO上的一个评价很高的例子:Retrieving the last record in each group

在您更新的查询中,子查询实际上是为我认为的每一行重新计算的。我们可以通过将读数加入自身来做得更好(查看以上链接作为参考)

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
;

device_id和date_created上的索引是提高速度的第一步

答案 3 :(得分:0)

我终于能够把它整理好了。以下查询在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);
            }

上面的查询在大约半秒内查询100K行,然后将其转换为laravel的集合,一次在集合i中按id分组,然后从该结果中获取最后一条记录。

感谢所有试图提供帮助的人:)