1

次の2つのテーブルがあります。

items:
 id int primary key
 bla text

events:
 id_items int
 num int
 when timestamp without time zone
 ble text
 composite primary key: id_items, num

そして、各項目に最新のイベント (最新の「いつ」) を選択したいと考えています。リクエストを書きましたが、もっと効率的に書けるかどうかわかりません。 また、PostgreSQL では、Timestamp オブジェクトの比較に問題があります: 2010-05-08T10:00:00.123 == 2010-05-08T10:00:00.321 なので、「MAX(num)」で選択します。 それを改善する方法はありますか?ありがとう。

SELECT i.*, ea.* FROM items AS i JOIN
( SELECT t.s AS t_s, t.c AS t_c, max(e.num) AS o FROM events AS e JOIN
( SELECT DISTINCT id_item AS s, MAX(when) AS c FROM events GROUP BY s ORDER BY c ) AS t
ON t.s = e.id_item AND e.when = t.c GROUP BY t.s, t.c ) AS tt
ON tt.t_s = i.id JOIN events AS ea ON ea.id_item = tt.t_s AND ea.cas = tt.t_c AND ea.num = tt.o;

編集: 悪いデータがありました。申し訳ありませんが、より良い SQL クエリを見つけてくれてありがとう

4

3 に答える 3

0

この種の結合には、DISTINCT ON構文 ( example ) を好みます。これは Postgresql 拡張 (SQL 標準構文ではない) ですが、非常に便利です。

SELECT DISTINCT ON (it.id) 
it.*, ev.*
FROM items it, events ev
WHERE ev.id_items = it.id
ORDER by it.id, ev.when DESC;

シンプルさと読みやすさの点で、これに勝るものはありません。

このクエリは、すべてのアイテムに少なくとも 1 つのイベントがあることを前提としています。そうでない場合、およびすべてのイベントが必要な場合は、外部結合が必要になります。

SELECT DISTINCT ON (it.id) 
it.*, ev.*
FROM items it LEFT JOIN events ev
ON ev.id_items = it.id
ORDER BY it.id, ev.when DESC;

ところで: Postgresql には「タイムスタンプの問題」はありません。おそらくタイトルを変更する必要があります。

于 2010-05-11T12:13:16.357 に答える
0
SELECT  (i).*, (e).*
FROM    (
        SELECT  i,
                (
                SELECT  e
                FROM    events e
                WHERE   e.id_items = i.id
                ORDER BY
                        when DESC
                LIMIT 1
                ) e
        FROM    items i
        ) q
于 2010-05-11T09:27:52.630 に答える
0

8.4 を使用している場合:

select * from (
  select item.*, event.*,
         row_number() over(partition by item.id order by event."when" desc) as row_number
  from items item
       join events event on event.id_items = item.id
) x where row_number = 1
于 2010-05-11T09:58:11.353 に答える