Фильтровать по значению в последней строке таблицы LEFT OUTER JOIN

У меня есть таблица Clients в PostgreSQL (версия 9.1.11), и я хотел бы написать запрос для фильтрации этой таблицы. Запрос должен возвращать только клиентов, отвечающих одному из следующих условий:

--Последний заказ клиента (основанный на базе данных orders.created_at) имеет дату выполнения в прошлом.

OR

--У клиента вообще нет заказов

Я искал около 2 месяцев, время от времени, для решения.

Я просмотрел пользовательские последние агрегатные функции в Postgres, но не смог заставить их работать и чувствовать, что должен быть встроенный способ сделать это.

Я также просмотрел функции окна postgres last_value, но большинство примеров относятся к одной таблице, а не к запросу, объединяющему несколько таблиц.

Любая помощь будет принята с благодарностью! Вот пример того, что я собираюсь сделать:

Clients table:  
| client_id | client_name  |
----------------------------
| 1         | FirstClient  |
| 2         | SecondClient |
| 3         | ThirdClient  |
Orders table:
| order_id | client_id | fulfill_by_date | created_at |
-------------------------------------------------------
| 1        | 1         | 3000-01-01      | 2013-01-01 |
| 2        | 1         | 1999-01-01      | 2013-01-02 |
| 3        | 2         | 1999-01-01      | 2013-01-01 |
| 4        | 2         | 3000-01-01      | 2013-01-02 |
Desired query result:
| client_id | client_name  |
----------------------------
| 1         | FirstClient  |
| 3         | ThirdClient  |

person Teddy Widom    schedule 29.12.2013    source источник


Ответы (1)


Попробуйте так

SELECT c.client_id, c.client_name
  FROM clients c LEFT JOIN
(
  SELECT *, ROW_NUMBER() OVER (PARTITION BY client_id ORDER BY created_at DESC) rnum
    FROM orders
) o 
    ON c.client_id = o.client_id
   AND o.rnum = 1
 WHERE o.fulfill_by_date < CURRENT_DATE
    OR o.order_id IS NULL

Выход:

| CLIENT_ID | CLIENT_NAME |
|-----------|-------------|
|         1 | FirstClient |
|         3 | ThirdClient |

Вот демонстрация SQLFiddle.

person peterm    schedule 29.12.2013