Хобрук: Ваш путь к мастерству в программировании

Возврат одной строки во ВНУТРЕННЕМ СОЕДИНЕНИИ

Я хотел бы вернуть первую строку только из внутреннего соединения. У меня есть две таблицы:

Строки в TABLE_D и TABLE_E могут иметь одинаковые даты создания, поэтому я сначала получаю MAX (дата создания), а затем MAX (id) из этого набора. Вот мой полный запрос:

SELECT
a.id as A_ID,
b.id as B_ID,
c.id as C_ID,
d.id as D_ID,
e.id as E_ID,
d.CREATIONDATE,
a.REFNUMBER,
a.DATECREATED,
a.INFO,
e.COST,
FROM 
TABLE_A a
INNER JOIN TABLE_B b ON (b.id = a.id)
INNER JOIN TABLE_C c ON (c.id = b.id)
INNER JOIN TABLE_D d ON
(
   c.i =
   (
      select
      d.id
      FROM TABLE_D
      WHERE TABLE_D.id = c.id
      AND TABLE_D.id =
      (
         select
         max(id)
         from TABLE_D t1
         where c_id = c.id
         and CREATIONDATE =
         (
            select
            max(CREATIONDATE)
            from TABLE_D t2
            where t2.c_id = t1.c_id
         )
      )
   ) 
)

INNER JOIN TABLE_E e ON
(
   d.i =
   (
      select
      e.d_id
      from TABLE_E
      where d_id = d.id
      AND id =
      (
         select
         max(id)
         from e t1
         where e.d_id = d.id
         and CREATIONDATE =
         (
            select
            max(CREATIONDATE)
            from TABLE_E t2
            where t2.d_id = t1.d_id
         )
      )
   )
)


Мой подзапрос для получения всех строк с максимальной датой создания, и поэтому максимальный идентификатор работает нормально, когда я вызываю его сам по себе, но когда я добавляю его во ВНУТРЕННЕЕ СОЕДИНЕНИЕ (см. выше), я получаю строку для каждой соответствующей строки в таблице D и таблица E. Мне нужна одна строка для TABLE_A.id, показывающая только последнюю строку из TABLE_D, связанную с TABLE_C, и последнюю строку из TABLE_E, связанную с TABLE_D.

Например, идентификаторы в моем наборе результатов на данный момент выглядят так:

--------------------------------------------------------------------------
A_ID            B_ID            C_ID            D_ID            E_ID
--------------------------------------------------------------------------
1               101             201             301             401
1               101             201             301             402    
1               101             201             301             403    
1               101             201             302             404
1               101             201             302             405    
1               101             201             302             406    

мне нужно вот это:

--------------------------------------------------------------------------
A_ID            B_ID            C_ID            D_ID            E_ID
--------------------------------------------------------------------------
1               101             201             302             406


Заранее спасибо за вашу помощь.

18.01.2011

Ответы:


1

Используйте аналитическую функцию ROW_NUMBER(), доступную в oracle11g.

SELECT *
FROM 
(
SELECT
    a.id as A_ID,b.id as B_ID,c.id as C_ID,d.id as D_ID,e.id as E_ID,
    d.CREATIONDATE,a.REFNUMBER,a.DATECREATED,a.INFO,e.COST,
    row_number() over (
        partition by a.id, b.id, c.id
        order by d.CREATIONDATE DESC, d.id desc, e.CREATIONDATE DESC, e.id desc) RN
FROM TABLE_A a
INNER JOIN TABLE_B b ON (b.id = a.id)
INNER JOIN TABLE_C c ON (c.id = b.id)
INNER JOIN TABLE_D d ON d.c_id = c.id
INNER JOIN TABLE_E e ON e.d_id = d.id
) N
WHERE RN = 1

Просто убедитесь, что предложения PARTITION и ORDER BY верны.

partition by a.id, b.id, c.id
    => start numbering from 1 again when any one of these changes
order by d.CREATIONDATE DESC, d.id desc, e.CREATIONDATE DESC, e.id desc)
    => number the rows in this order
18.01.2011

2

Что бы я сделал, так это переместил внутренний запрос в предложение выбора. Я просто оставлю прямое сопоставление при фильтрации

SELECT
a.id as A_ID,
b.id as B_ID,
c.id as C_ID,
(select max(d.id) from d where d.id =c.id) as d_id)
FROM 
TABLE_A a
INNER JOIN TABLE_B b ON (b.id = a.id)
INNER JOIN TABLE_C c ON (c.id = b.id)
18.01.2011

3

Вы можете вставить свой запрос в подзапрос и использовать фильтр WHERE ROWNUM‹2.

SELECT * FROM
(/* Your SQL */)
WHERE ROWNUM < 2
18.01.2011
  • К сожалению, это не сработает, так как мне нужна строка для каждого A_ID. Я просто поместил один результат в свой пример, чтобы показать, что мне нужны последние D_ID и E_ID для каждого A_ID. Спасибо хоть. 18.01.2011

  • 4

    Может быть, это сработает для вас?

    SELECT TOP 1
    a.id as A_ID,
    b.id as B_ID,
    c.id as C_ID,
    d.id as D_ID,
    e.id as E_ID,
    d.CREATIONDATE,
    a.REFNUMBER,
    a.DATECREATED,
    a.INFO,
    e.COST,
    FROM 
    TABLE_A a
    INNER JOIN TABLE_B b ON (b.id = a.id)
    INNER JOIN TABLE_C c ON (c.id = b.id)
    INNER JOIN TABLE_D d ON (c.i = d.id)
    INNER JOIN TABLE_E e ON ( d.i = e.id )
    ORDER BY d.creationdate DESC, e.creationdate DESC
    
    18.01.2011
  • SELECT TOP 1 нельзя использовать в Oracle 17.09.2012
  • Новые материалы

    Создание кнопочного меню с использованием HTML, CSS и JavaScript
    Вы будете создавать кнопочное меню, которое имеет состояние наведения, а также позволяет вам выбирать кнопку при нажатии на нее. Финальный проект можно увидеть в этом Codepen . Шаг 1..

    Внедрите OAuth в свои веб-приложения для повышения безопасности
    OAuth — это широко распространенный стандарт авторизации, который позволяет приложениям получать доступ к ресурсам от имени пользователя, не раскрывая его пароль. Это позволяет пользователям..

    Классы в JavaScript
    class является образцом java Script Object. Конструкция «class» позволяет определять классы на основе прототипов с чистым, красивым синтаксисом. // define class Human class Human {..

    Как свинг-трейдеры могут использовать ИИ для больших выигрышей
    По мере того как все больше и больше профессиональных трейдеров и активных розничных трейдеров узнают о возможностях, которые предоставляет искусственный интеллект и машинное обучение для улучшения..

    Как построить любой стол
    Я разработчик программного обеспечения. Я люблю делать вещи и всегда любил. Для меня программирование всегда было способом создавать вещи, используя только компьютер и мое воображение...

    Обзор: Машинное обучение: классификация
    Только что закончил третий курс курса 4 часть специализации по машинному обучению . Как и второй курс, он был посвящен низкоуровневой работе алгоритмов машинного обучения. Что касается..

    Разработка расширений Qlik Sense с qExt
    Использование современных инструментов веб-разработки для разработки крутых расширений Вы когда-нибудь хотели кнопку для установки переменной в приложении Qlik Sense? Когда-нибудь просили..