2017-01-13 4 views
0

私はここで他のほとんどのソリューションを見てきましたが、どれも私にとってはうまくいかないようです。私は約100K行のテーブルを持っています。laravel 5.3 - 結果はどこからmysql

各行は、そのデバイスの一意のIDを含むiotデバイスのレコードです。デバイスIDは、100Kから10Kの行を持つことができます。

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

私は上記のクエリとして「DEVICE_ID」で一緒に私は必要なIDとグループにそれらを引き出すことが可能だが、その各IDの最後の最初の結果を選ぶとありません。

最も古いレコードではなく、各レコードの最新レコードを取得するにはどうすればよいですか?

私はlaravelコレクションとreverse()、first()、latest()を見てきました。私はまだそれを得ることはできません

すべてのアイデア?

UPDATE

私が思い付くことができた最高のは、それぞれの最新のレコードをつかむし、それ以下このクエリは、私はそれらをループその後、よ

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) 

をDEVICE_IDであります結果を表示し、ユーザーがアクセスできるレコードのみを取得します。

これはあまり意味がありませんが、現在は機能しています。

誰が今まで私は、これは動作するはずと信じて

答えて

0

をお答えください雄弁にそれを行うには離れて見つけない場合は?

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

以前の試みはしなかったよう

+0

助けようとしたすべての人に

ありがとう:あなたはおそらく、渡された – ATechGuy

+0

「Grammar.phpラインでErrorException 58)(strtolowerは、パラメータ1は、オブジェクトが与えられた文字列であることを期待します」オブジェクトのインスタンス...コードを表示する – GabMic

+0

どのコードeitan?私のコードは上記ですが、$ idsは配列 – ATechGuy

0

OK、私は、これが機能すると考えている:

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

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

あなたは基本的に「サブクエリ」を実行します。したがって、必要な順序で結果を取得し、2番目のクエリを実行してグループ化します。

+0

これに注意してください。ストレージエンジンとインデックスに応じて順序がオフになる可能性があります – nkconnor

0

これはちょっと難しい質問です。一度データベースの用語集で質問を再構築すると、「MySQLクエリの各IDの最大レコードを取得する」のように、多くのSO答えを見つけるのは簡単です。ここで

がSOで高い評価を例です:あなたの更新クエリでRetrieving the last record in each group

、サブクエリは実際に私が考える行ごとに再計算されます。私は最終的にそれが出てソートを取得することができた我々は(参照としてリンク上でご確認ください)自体に測定値を結合してDEVICE_IDに

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 
; 

インデックスをよりよく行うことができ、この速い

+0

また、別のwhere句 'AND r2.device_id IN($ ids)'を追加できることを覚えていて、数字の場合は 'r2.device_id>($ lowest_id )とr2.device_id <($ highest_id) 'となります。これはコード内の結果をループするよりも良いでしょう。 – nkconnor

0

を作るための簡単な最初のステップは、DATE_CREATEDです。次のクエリは、私が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); 
      } 

このクエリは、上記その後、idで一度コレクションI群では、laravelのためのコレクションにそれを回して、約半分秒で100Kの行を照会している、その結果から最後のレコードをつかみます。私はこの 取得:)