2011-12-08 16 views
2

私は2つのテーブルを持っています.1つはイベントと呼ばれ、もう1つはドキュメントです。各テーブルには、開始と終了の2つの日付列(イベント開始、イベント終了、文書開始、文書終了)があります。どちらのテーブルもCustomer_IDというフィールドでリンクされています。別のテーブルで最も近い日付を返す

Customer_ID DOC_ID  DOC_Start DOC_END 
A   12   22/01/2011 23/01/2011 
A   13   01/12/2011 05/12/2011 
C   22   13/03/2011 20/03/2011 


Customer_ID Event_ID Event_Start Event_END 
A   J1   01/01/2011 23/01/2011 
A   J2   04/12/2011 05/12/2011 
C   J44   15/03/2011 20/03/2011 

私は思います。たとえば、テーブル内のデータがどのように見えるかもしれませんので、私は、最も近い関連するイベントの開始(およびそのID)、顧客IDに基づいて、ドキュメントの開始日までの日付を返すに興味最終結果はこれを表示したい:私は解決策をグーグルで試してみました、1つのまたは2つの提案を試みたが、私は見つけることができる例はいずれも、あるいは用テーブル間の日付を比較するためであると思わなかっまし

Customer_ID DOC_ID DOC_Start DOC_END  Event_ID 
A   12  22/01/2011 23/01/2011 J1 
A   13  01/12/2011 05/12/2011 J2 
C   22  13/03/2011 20/03/2011 J44 

オラクルまた、SQLについてはかなり知識が限られていますが、私が取り上げたものはここから来ているので、すでに手伝ってくれてありがとう。

編集:さらなる条件は、関連するイベント/ドキュメントタイプのみを返すことです。ですから、DOC_TYPEが 'Inquiry'や 'Info'のDOC_IDを戻したいだけで、Event_Typeの場合も同じです。

編集:おかげでヴィンセント、私はどこに示唆(私はどこでもそれを試してみたと思うが!)と私は今結果を得る必要があります。

誰もが興味を持っている場合、私は今後の参考のための実用的なソリューションを投稿します:

SELECT 
* 

FROM (SELECT 
O_ASSESSMENTS.ASM_SUBJECT_ID as "ID", 
O_ASSESSMENTS.ASM_ID as "Assessment ID", 
O_ASSESSMENTS.ASM_START_DATE as "Assessment Start", 
O_ASSESSMENTS.ASM_END_DATE as "Assessment End", 
O_SERVICE_EVENTS.SEV_ID as "Event ID", 
O_SERVICE_EVENTS.SEV_ACTUAL_DATE as "Event Start", 
O_SERVICE_EVENTS.SEV_OUTCOME_DATE as "Event End", 
ROUND(O_ASSESSMENTS.ASM_START_DATE -O_SERVICE_EVENTS.SEV_ACTUAL_DATE,0) as "Likely", 
    row_number() over(PARTITION BY O_ASSESSMENTS.ASM_ID          
ORDER BY abs(O_ASSESSMENTS.ASM_START_DATE - O_SERVICE_EVENTS.SEV_ACTUAL_DATE)) rn    
FROM 
O_ASSESSMENTS 
JOIN O_SERVICE_EVENTS ON O_ASSESSMENTS.ASM_SUBJECT_ID = O_SERVICE_EVENTS.SEV_SUBJECT_ID 
Where O_SERVICE_EVENTS.SEV_CODE IN ('t','t1') AND O_ASSESSMENTS.ASM_QSA_ID IN ('test','test1') ) WHERE rn = 1 
+0

'event_start'は' DOC_start'状態の前に来ることができますが、それでも最も近いと考えられますか?あるいは 'event_start'は常に後でなければならないのでしょうか? – ean5533

+0

はい、可能です。 :) – bawpie

答えて

8

をあなたはanalyticsを使用することができます。

SELECT * 
    FROM (SELECT d.customer_id, d.doc_id, d.doc_start, d.doc_end, e.event_id, 
       row_number() over(PARTITION BY d.doc_id 
            ORDER BY abs(d.doc_start - e.event_start)) rn 
      FROM doc d 
      JOIN event e ON d.customer_id = e.customer_id 
     /*WHERE CLAUSE*/) 
WHERE rn = 1 
+0

ありがとうございます、これはいくつかの結果をもたらしているようですが、私はさらに条件を追加する必要があるでしょう - ドキュメントテーブルでは、私は特定のドキュメントタイプにのみ興味があり、イベントテーブルにも同じです。私は結果のコードを調整することができると思ったので、私は元のクエリにこれを含めなかったが、どこにクエリを追加しようとすると、エラーが発生する...私は更新するeleborateへの元のクエリ – bawpie

+0

内部クエリにwhere句を追加することができます。更新されたクエリを参照してください。 –

+0

ありがとうございましたVincent、これはこのトリックを行っているようです。どうもありがとう! – bawpie

0

EventsDocumentsに参加して、唯一の最も近いDOC_Startで結合された行を選択しますおよびEvent_Start

select D1.Customer_ID, D1.DOC_ID, D1.DOC_Start, D1.DOC_END, E1.Event_ID 
from Events E1, Documents D1 
where E1.Customer_ID = D1.Customer_ID 
and (D1.Customer_ID, D1.DOC_ID, E1.Event_ID) in 
(
    select D2.Customer_ID, D2.DOC_ID, E2.Event_ID 
    from Events E2, Documents D2 
    where E2.Customer_ID = D2.Customer_ID 
    group by D2.Customer_ID, D2.DOC_ID, E2.Event_ID 
    having abs(D2.DOC_Start - E2.Event_Start) = min(abs(D2.DOC_Start - E2.Event_Start)) 
); 
+0

これを投稿していただきありがとうございます、残念ながら私はこれを動作させるのに少し問題がありましたが、私は限られたSQL知識をクエリの問題よりも多くすると思います。ありがとう! – bawpie