2013-04-01 2 views
0

У меня есть три таблицы:Извлечение значений из 3 таблиц

  1. Потребитель, который имеет поля cons_id_no, KEY_ID
  2. bm_bill, который имеет поля KEY_ID, bill_id_no, amt_payable, bill_date (Он будет содержать все вексельных сумм и дата потребителя)
  3. mreceipt, который имеет поля KEY_ID, receipt_no, amt_paid, хорошо, pay_date (Он будет содержать все платежные реквизиты потребителя)

Стол для потребителя имеет отношение к bm_bill и mreceipt. Я хочу создать бухгалтерскую информацию потребителя на основе его cons_id_no. Он должен содержать его cons_id_no, key_id, bill_id_no (последний), bill_date (последний), amt_payable (последний), receipt_no (последний), amt_paid (последний), штраф (последний), pay_date (последний), и для этого я создал ниже запрос

Я задал вопрос here и я узнал одно решение, но все же этого было недостаточно, как это было получения всей информации из таблиц счетов и платежей. По кончике меня оттуда, я достиг еще одно решение, которое выглядит следующим образом:

Прежде всего я создал тип:

CREATE OR REPLACE TYPE key_id_row AS OBJECT 
    (
     key_id number(10) 
    ); 

Затем создал тип таблицы:

CREATE OR REPLACE TYPE key_id_tab AS TABLE OF key_id_row; 

Затем создал функцию:

CREATE OR REPLACE FUNCTION get_key_id(cons_id VARCHAR2) RETURN key_id_tab IS 
    result_tab key_id_tab;  
BEGIN 
    SELECT 
     key_id_row(key_id) 
    BULK COLLECT INTO 
     result_tab 
    FROM 
     consumer 
    WHERE 
     cons_id_no = cons_id; 
    RETURN result_tab;  
END get_key_id; 

После того, что я использовал его в запросе следующим образом:

SELECT 
    c.key_id, 
    c.cons_id_no consumerid, 
    b.bill_id_no, 
    b.key_id, 
    b.bill_date, 
    m.key_id, 
    m.receipt_no, 
    m.pay_date  
FROM 
    consumer c 
LEFT OUTER JOIN 
    (
     SELECT 
      bb.bill_id_no, 
      gk.key_id, 
      bb.bill_date, 
      ROW_NUMBER() OVER (PARTITION BY bb.key_id ORDER BY bb.bill_date DESC) AS rowNumber 
     FROM 
      bm_bill bb 
     JOIN 
      TABLE(get_key_id('2114109999')) gk 
     ON 
      (gk.key_id = bb.key_id)  
    ) b 
ON 
    (b.rowNumber = 1) 
LEFT OUTER JOIN 
    (
     SELECT 
      gk.key_id, 
      mr.receipt_no, 
      mr.pay_date, 
      ROW_NUMBER() OVER (PARTITION BY mr.key_id ORDER BY mr.pay_date DESC) rowNumber 
     FROM 
      mreceipt mr 
     JOIN 
      TABLE(get_key_id('2114109999')) gk 
     ON 
      (gk.key_id = mr.key_id) 
    ) m 
ON 
    (m.rowNumber = 1)   
WHERE 
    c.cons_id_no='2114109999'; 

Является ли решение достаточно хорошо, или я должен подойти к проблеме следующим образом:

Выберите KEY_ID из таблицы потребителя в виде отдельного запроса, как в:

SELECT key_id FROM consumer WHERE cons_id_no = '2114109999'; 

и сохранить его в переменной и использовать это значение в запросе, о котором я упоминал выше.

ответ

0

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

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

Вы хотите, чтобы ваша книга была полным списком всех счетов и платежей потребителем? Ваш вопрос создает впечатление, что вы заботитесь только о последних.

+0

Мне нужно только последнее. В предыдущем запросе запрос в левом внешнем соединении извлекает все строки из таблицы. Чтобы избежать этого, я использовал функцию, теперь я думаю, что это перебор. – kaushik

+0

Хорошо.Подзапросы в решении будут запрашивать полную таблицу, но вы можете использовать индексы и таблицы, чтобы помочь определить, где искать эти таблицы для ранжирования, однако на основе реализации они возвращают только первую запись, где rownum = 1, поэтому, если он возвращает много записей, в вашей реализации что-то не так. Я согласен, что использование функции слишком велико, потому что вам действительно нужна только одна запись из каждой из исходных таблиц. – KDoyle

Смежные вопросы