2017-08-25 7 views
3

私は面接のプロセスを通じて満たされている行を持つOracle DBのテーブル構造を持っている中で最も新しい行を表示するには、各「顧客が」インタビュープロセスを経ることができます即日。テーブルの構造は次のようになります。SQLクエリがデータを持つテーブル、またはnull

Table: Customers 
------------- 
CustomerId 
... 

Table: Questions 
------------- 
QuestionId | QuestionText 
0   | Last Location? 
1   | Last Color? 
2   | Last Food? 
3   | Last Drink? 

Table: Answers 
------------- 
Id | CustomerId | QuestionId | AnswerText | Created_On 
1 0   0   Chicago  08/15/2017 7:56:34 AM 
2 0   0   Laramie  08/16/2017 9:27:23 AM 
3 0   0   Null   08/17/2017 6:34:56 AM 
4 0   1   Null   08/15/2017 7:56:34 AM 
5 0   1   Green  08/16/2017 9:27:23 AM 
6 0   1   Blue   08/17/2017 6:34:56 AM 
7 0   2   Pizza  08/15/2017 7:56:34 AM 
8 0   2   Null   08/16/2017 9:27:23 AM 
9 0   2   Null   08/17/2017 6:34:56 AM 
10 0   3   Null   08/15/2017 7:56:34 AM 
11 0   3   Null   08/16/2017 9:27:23 AM 
12 0   3   Null   08/17/2017 6:34:56 AM 

は現在、我々はこのように、それは価値があるか、NULLかどうかを、各質問に対する最新のタイムスタンプのためのデータを照会し、その結果を示すことによって、「最後のインタビュー」を表示します:

LastAnswer_QueryResult 
------------- 
Id | CustomerId | QuestionId | AnswerText | Created_On 
3 0   0   Null   08/17/2017 6:34:56 AM 
6 0   1   Blue   08/17/2017 6:34:56 AM 
9 0   2   Null   08/17/2017 6:34:56 AM 
12 0   3   Null   08/17/2017 6:34:56 AM 

新しい要件は、質問が回答されていない場合、値はnullで、各質問のための最新の答えを示すことです。これまでのところ私が思い付くことができます最善のアプローチは、ループ内で、その後、一時テーブルに最も古い行を挿入することである

MostRecentAnswer_QueryResult 
Id | CustomerId | QuestionId | AnswerText | Created_On 
2 0   0   Laramie  08/16/2017 9:27:23 AM 
6 0   1   Blue   08/17/2017 6:34:56 AM 
7 0   2   Pizza  08/15/2017 7:56:34 AM 
12 0   3   Null   08/17/2017 6:34:56 AM 

:私はサンプルデータのクエリに正しい結果を得ることができた場合は、上記のようになります。新しいタイムスタンプで値が存在する場合は、値を更新します。その後、完了したら、最新のタイムスタンプでヌル値を更新します。私はこれをループせずに、一時テーブルに挿入する方法がありますか?

答えて

2

レスキュー機能の分析機能!パーティションをcustomeridquestionidに変更し、各パーティションの行にrow_number()を割り当てます。 answertext is nullについて心配する必要がなければ、単にcreated_on descで注文します。

nullを処理するには、answertextがヌルでないかnullであるかによって最初に注文します。これはcase式で簡単に行えます(下記参照)。

外部クエリでは、row_numberが1(すべての組み合わせがcustomeridquestionid)の行を選択します。あなたが試すことができ

select id, customerid, questionid, answertext, ts 
from (
     select id, customerid, questionid, answertext, ts, 
       row_number() over (partition by customerid, questionid 
             order by case when answertext is not null 
                 then 0 end, 
               created_on desc 
           ) as rn 
     from answers 
     ) 
where rn = 1 
; 
+0

感謝を拳名AnswerTextを取得します - 私は実際に難読化しなければなりませんでした列名は予約語であることを忘れてしまいました。サンプルで修正されました。 –

0

:その後

select MAX(a.id) ID, a.CustomerId , q.QuestionId,LISTAGG(AnswerText,' * ') WITHIN GROUP (ORDER BY ID) AnswerText, max(a.Created_On) Created_On 
    from Questions q 
    left join Answers a 
    on a.QuestionId = q.QuestionId 
    where a.AnswerText is not null 
    group by a.CustomerId , q.QuestionId 
    UNION ALL 
    select MAX(a.id) ID, a.CustomerId , q.QuestionId ,LISTAGG(AnswerText,' *') WITHIN GROUP (ORDER BY ID) AnswerText, max(a.Created_On) Created_On 
    from Questions q 
    left join Answers a 
    on a.QuestionId = q.QuestionId 
    where a.AnswerText is null AND 
    Q.QuestionId NOT IN(
     select q.QuestionId 
     from Questions q 
     left join Answers a 
     on a.QuestionId = q.QuestionId 
     where a.AnswerText is not null 
     group by a.CustomerId , q.QuestionId 
    ) 
    group by a.CustomerId , q.QuestionId 
    ORDER BY QuestionId 

を、あなたは「*」の間で「タイムスタンプ」についてのノートの

関連する問題