2017-01-12 14 views
0

テーブルを使用して、特定のレコードのステータスが変更された日付と時刻をentriesに保存すると、現在のステータスを取得する最も簡単な方法を見つけようとしています、AKA、最新の日付のステータス。例えばDoctrine 2 - 履歴テーブルから最新のレコードを取得する

次の点を考慮してくださいstatus_history

+----+----------+------------+-----------+ 
| id | entry_id | status | timestamp | 
+----+----------+------------+-----------+ 
| 1 |  1 | Processing | 15:05:09 | 
| 2 |  1 | In Review | 15:05:18 | 
| 3 |  1 | Complete | 15:05:26 | 
+----+----------+------------+-----------+ 

そしてもちろん、私たちのエントリ:entries

+----+--------+ 
| id | title | 
+----+--------+ 
| 1 | Foobar | 
+----+--------+ 
私が取得することができますどのように

DQL、(技術的に最新の状態で現在のステータス)をのlatest_status_idの列を私のEntryエンティティ?

$entry->getCurrentStatus()を呼び出すと、"Complete"が返されるとします。しかし、そのエントリーに大量の状況レコードがある場合、すべての状況をロードするための2番目の照会がパフォーマンス低下につながる可能性があります。

注:this articleでは、並行処理のためのロック機構を使用して、余分な列のアプローチで説明しています。私は各テーブル(status_history.entry_identry.latest_history_id)の二重の関係を持たないようにしようとしているので、これが正しいものでない限り、このアプローチを避けたいと思います。

+0

'$ entry'をどのように取得しますか? – JimL

+0

もちろんDQLを使用しています。しかし、クエリそのものは、それが状態の最後の行をもたらすという考えから、私が把握しようとしていることです。 –

+0

質問があなたが把握しようとしているものであれば、投稿に追加することをお勧めします。人のための障壁を低くして、正しい方向に助けを借りて声をかけることがあります。 – JimL

答えて

0

私はあなたのステータス履歴リポジトリ内QueryBuilderを使用すると、これは十分であろうと思う:

$entry_id = 1; 
$queryBuilder = $this->createQueryBuilder() 
    ->select('s') 
    ->where('s.entry = :entry_id') 
    ->orderBy('o.id', 'DESC') 
    ->setParameter('entry_id', $entry_id) 
$query = $queryBuilder->getQuery(); 
return $query->getSingleResult(); 

あなたはidが「自動インクリメント」であるとtimestampは、の作成の自動タイムスタンプであると仮定すると、IDを使用することができますあなたの記録。そのような場合、最も高いIDは常に最新の挿入文字なので、そのレコードを見つけるためにtimestampカラムを使用する必要はありません。

そうでなければ、あなたが代わりにその列によって、あなたのtimestamp列と順番にインデックスを追加する必要があります。

$entry_id = 1; 
$queryBuilder = $this->createQueryBuilder() 
    ->select('s') 
    ->where('s.entry = :entry_id') 
    ->orderBy('o.timestamp', 'DESC') 
    ->setParameter('entry_id', $entry_id) 
$query = $queryBuilder->getQuery(); 
return $query->getSingleResult(); 

あなたは、単一のエントリのためにパフォーマンスを向上させるために、あなたのtimestamp

+0

あなたはIDの代わりにタイムスタンプで注文するべきではありませんか? – flec

+0

それは異なります。それは必要ではないかもしれません。答えの下のコメントをお読みください。 – Wilt

1

にインデックスを追加する必要がありますクエリは次のようになります。

$query = $em->createQuery('SELECT e, s 
    FROM entries e 
    JOIN e.status_history s 
    WHERE e.entry_id = :entry_id 
    ORDER BY s.timestamp DESC'); 
$query->setParameter('entry_id', $entry_id); 
$entries = $query->getSingleResult(); 

getCurrentStatus()メソッドでは、割り当てられたstatus_historyオブジェクトのみ。

すべてのエントリについて、それはより複雑で、GROUP BYMAX()のサブクエリを使用する必要があります。ネイティブSQLでは実現可能ですが、DQLを使用してSQLを実行する方法はわかりません。私は解決策が得られるとすぐに私の答えを更新します。

関連する問題