PL / SQL - Как получить данные из 3 таблиц на основе последней даты создания - PullRequest
2 голосов
/ 15 марта 2010

Я надеюсь, что кто-то может мне помочь, так как я застрял в этой проблеме в течение нескольких дней.В основном я пытаюсь получить данные из 3 таблиц в Oracle: 1) Таблица заказов 2) Таблица поставщиков и 3) Таблица основных данных.

Вот как выглядят эти 3 таблицы:

Таблица1: BIZ_DOC2 (таблица заказов)

OBJECTID (уникальный ключ)
UNIQUE_DOC_NAME (имя документа т.е. ORD-005)
CREATED_AT (дата создания заказа)

Таблица 2:UDEF_VENDOR (таблица поставщиков):

PARENT_OBJECT_ID (совпадает с OBJECTID в таблице заказов)
VENDOR_OBJECT_NAME (это имя поставщика, т.е. Acme)

Таблица 3: BIZ_UNIT(Таблица основных данных)

PARENT_OBJECT_ID (Соответствует OBJECTID в таблице заказов)
BIZ_UNIT_OBJECT_NAME (Это название бизнес-единицы, т.е. виджет A, виджет B)

Примечание. Таблица поставщиков и основные данные не имеют связи между ними, кроме как через таблицу «Заказы».

Я могу объединить все данные из таблиц, и это выглядит примерно так:

Перед продажейдата последнего заказа:

ORD-005 |Виджет А |Acme |3/14/10
ORD-005 |Виджет Б |Acme |3/14/10
ORD-004 |Виджет C |Acme |3/10/10

В идеале я хотел бы вернуть последний заказ для каждого поставщика.Однако каждый заказ может содержать несколько бизнес-единиц (например, типы виджетов), поэтому, если последняя запись Продавца ORD-005 и заказ содержит 2 бизнес-единицы, вот как должен выглядеть набор результатов в следующих столбцах: UNIQUE_DOC_NAME, BIZ_UNIT_OBJECT_NAME,VENDOR_OBJECT_NAME, CREATED_AT

После выбора по дате последнего заказа:

ORD-005 |Виджет А |Acme |3/14/10
ORD-005 |Виджет Б |Acme |3/14/10

Я пытался использовать Select Max и несколько вариантов подзапросов, но мне просто не удается заставить его работать.Любая помощь будет принята с благодарностью!

Ответы [ 3 ]

3 голосов
/ 15 марта 2010
SELECT DISTINCT
       FIRST_VALUE(d.unique_doc_name)
       OVER (PARTITION BY v.vendor_object_name
             ORDER BY d.created_at DESC)
       AS unique_doc_name
      ,FIRST_VALUE(u.biz_unit_object_name)
       OVER (PARTITION BY v.vendor_object_name
             ORDER BY d.created_at DESC)
       AS biz_unit_object_name
      ,FIRST_VALUE(v.vendor_object_name)
       OVER (PARTITION BY v.vendor_object_name
             ORDER BY d.created_at DESC)
       AS vendor_object_name
      ,FIRST_VALUE(d.created_at)
       OVER (PARTITION BY v.vendor_object_name
             ORDER BY d.created_at DESC)
       AS created_at
FROM   biz_doc2 d, udef_vendor v, biz_unit u
WHERE  d.objectid = v.objectid
AND    d.objectid = u.parent_object_id;
2 голосов
/ 15 марта 2010
SELECT
  O.UNIQUE_DOC_NAME,
  U.BIZ_UNIT_OBJECT_NAME,
  V.VENDOR_OBJECT_NAME,
  O.CREATED_AT
 FROM
  ( SELECT
      V.VENDOR_OBJECT_NAME, MAX(O.CREATED_AT) AS CREATED_AT
     FROM
      UDEF_VENDOR AS V
     INNER JOIN
      BIZ_DOC2 AS O
     ON
      V.PARENT_OBJECT_ID=O.OBJECTID
     GROUP BY
      V.VENDOR_OBJECT_NAME
  ) AS VO   -- most recent order date per vendor
 INNER JOIN
  UDEF_VENDOR AS V
 ON
  V.VENDOR_OBJECT_NAME=VO.VENDOR_OBJECT_NAME
 INNER JOIN
  BIZ_DOC2 AS O
 ON         -- re-match vendors to orders for latest date
  O.OBJECTID=V.PARENT_OBJECT_ID AND
  O.CREATED_AT=VO.CREATED_AT
 INNER JOIN
  BIZ_UNIT AS U
 ON
  U.PARENT_OBJECT_ID=O.OBJECTID
0 голосов
/ 15 марта 2010

Вот еще одно решение с использованием аналитических функций. Вместо получения первого значения для максимальной даты, он ранжирует даты и получает все значения для самой последней даты.

select unique_doc_name, biz_unit_object_name, vendor_object_name, created_at
from (select unique_doc_name, biz_unit_object_name,
             vendor_object_name, created_at,
             rank () over (order by created_date desc) rnk
      from biz_doc2 d, udef_vendor v, biz_unit u
      where d.object_id = v.parent_object_id
      and d.objectid = u.parent_object_id)
where rnk = 1;
...