2

テーブルの場所にある各デバイスの最後の行を返す必要があります

私のテーブル名は次のとおりです。場所

+------------+----------+--------------+--------------+----------+  
| locationId | deviceId | dataRegistro | horaRegistro | location |  
+------------+----------+--------------+--------------+----------+  
|         50 |        1 |   2012-11-07 |     15:35:00 |      A12 |  
+------------+----------+--------------+--------------+----------+  
|         51 |        1 |   2012-11-07 |     15:37:40 |       B2 |  
+------------+----------+--------------+--------------+----------+  
|         52 |        2 |   2012-11-07 |     15:35:12 |       B8 |  
+------------+----------+--------------+--------------+----------+  
|         53 |        2 |   2012-11-07 |     15:35:40 |      50C |  
+------------+----------+--------------+--------------+----------+  
|         54 |        2 |   2012-11-07 |     15:40:00 |      94A |  
+------------+----------+--------------+--------------+----------+  

私が行う1つのデバイスから最後の行を選択する

select L from Location L where deviceId = :deviceId order by "dataRegistro" DESC, "horaRegistro" DESC limit 1

すべてのデバイスの最新の場所をすべて選択するにはどうすればよいですか? :(私はJava JPAを使用しています。

ありがとう、

エヴァンドロ

4

7 に答える 7

5

ID が順序付けられているため、後で記録されたレコードが後の日付に対応する場合は、次のクエリを使用できます (文字列を日付に変換する手間がかからないため、許容範囲よりも遅くなります)。

select L from Location L where deviceId = :deviceId order by L.locationId DESC 

Java コードで返される行数を制限します。

//EntityManager em; defined earlier
Query q = em.createQuery("select L from Location L where deviceId = :deviceId order by L.locationId DESC ");
q.setParameter("deviceId", "theDeviceIdIWantToQuery");
q.setMaxResults(1);
List<Location> results=query.getResultList();

これは、指定された deviceId の行がない場合、空のリスト、または 1 つの Location アイテム (最後のもの) を含むリストになります。

一度にすべてのデバイスの最新の場所を選択する場合は、IN 句とサブクエリを使用できます。

select L2 FROM Location L2 WHERE L2.locationId IN
    (select L.locationId from Location L 
    where L.deviceId = :deviceId 
    order by L.locationId DESC 
    group by L.deviceId)

悲しいことに、JPQL は FROM 句でサブクエリを使用することを許可していないため、これを行うのは私の選択ですが、ネイティブのクエリ関数を使用することによってのみ可能であり、使用するのははるかに不便です。

ちなみに、私の意見では、あなたのようにタイムスタンプを保存するのは悪い習慣です。適切にインデックス付けできず、クエリと注文の際に問題が発生します。単なる悪夢です。あなたのスキーマのこの部分を真剣に考え直します。

于 2012-11-08T13:44:22.803 に答える
1

はい、JPAを使用しています。この例は、必要なものを示すためのものです

1つのデバイスを選択するための私のJPAクエリは

Query q = em.createQuery("select TL from TRKLocation TL where   
TL.device.deviceId = :deviceId and TL.msgError = '' order by 
TL.dataRegistro DESC, TL.horaRegistro DESC");
        q.setParameter("deviceId", deviceId);           
        q.setMaxResults(1);

list = q.getResultList();

今、すべてのデバイスから最後の場所を選択するクエリが必要です:)

于 2012-11-08T13:32:57.040 に答える
0

このようなものはどうですか:

SELECT locationId
  FROM location
 WHERE dateregistro + horaregistro = (SELECT MAX(datergistro + horaregistro)
                                        FROM location
                                       WHERE deviceid = :deviceid)
   AND deviceid = :deviceid

日付の計算が正しいかどうかはわかりませんが、日付と時刻を組み合わせた新しい列を作成できる可能性があります。

于 2012-11-08T13:21:38.497 に答える
0

dateregistro と horaregistro が文字列の場合、次のクエリを試すことができます。

select * from location l1
where dateregistro + horaregistro = (select max(dateregistro + horaregistro) from
location l2 where l2.deviceid = l1.deviceid)

フィールドが一意でソートされたキーである場合は、そのlocationidフィールドに where 条件を適用できます。

select * from location l1
where locationid = (select max(locationid) from
location l2 where l2.deviceid = l1.deviceid)
于 2012-11-08T14:25:14.900 に答える
0

日付と時刻の 2 つの列ではなく、単純なタイムスタンプを保存しない理由がわかりません。これにより、必要な選択を実行することが難しくなります。これは、タイムスタンプが利用可能な場合にどのように機能するかの例です (JPQL 仕様セクション 4.6.16 を調べると、これが機能するはずです)。

Select loc From Location loc where loc.ts_registered = 
(Select MAX(subloc.ts_registered) From Location subloc where subloc.deviceId = loc.deviceId)

私はそれをテストしませんでしたが、これはうまくいくはずです。ただし、このクエリは中規模から大規模のデータ セットでは非常に遅くなることに注意してください。deviceId 列に必ずインデックスを追加する必要があります。

さらに、このクエリではデカルト積を作成する必要があるため、データ モデルを再考することをお勧めします (データが増えるとすぐに遅くなります)。

于 2012-11-08T14:06:47.857 に答える
0

これを試して

select top (1) location from location where deviceid=:deviceid 
 order by dateregistro,horaregistro desc
于 2012-11-08T13:15:29.953 に答える