0

SQLクエリについて少し助けが必要です。

次のような形式とデータを持つテーブルがあります。

id | applicant_id | application_status | status_time
1  | 1234         | received           | 2013-05-06 15:00:00
1  | 1234         | pending            | 2013-05-06 15:30:00
1  | 1234         | approved           | 2013-05-06 16:00:00

私が解決する必要がある問題は、次を印刷する必要があります。

applicant_id | initial_status | initial_time        | current_status | current_status_time
1234         | received       | 2013-05-06 15:00:00 | approved       | 2013-05-06 16:00:00

できれば結合のみを使用し、ネストされた選択を使用しないで、このようなことを達成するにはどうすればよいですか?

4

6 に答える 6

1

データベース製品については言及していませんが、どのデータベースでも次のようなものを使用できます。

select t1.id,
  t1.applicant_id,
  max(case when t1.status_time = t2.mintime then t1.application_status end) initial_status,
  max(case when t1.status_time = t2.mintime then t1.status_time end)initial_time,
  max(case when t1.status_time = t2.maxTime then t1.application_status end) current_status,
  max(case when t1.status_time = t2.maxTime then t1.status_time end) `current_time`
from yourtable t1
inner join
(
  select id, applicant_id,
    max(status_time) maxTime,
    min(status_time) mintime
  from yourtable
  group by id, applicant_id
) t2
  on t1.id = t2.id
  and t1.applicant_id = t2.applicant_id
  and 
  (
    t1.status_time = t2.mintime
    or t1.status_time = t2.maxtime
  )
group by t1.id, t1.applicant_id;

デモでSQL Fiddle を参照してください

于 2013-05-06T21:47:53.210 に答える
1

一般に、これにアプローチする最善の方法は、row_number()関数を使用することです。ただし、これにはネストされた選択が必要です。

select t.applicant_id,
       max(case when seqnum_asc = 1 then status end) as initial_status,
       max(case when seqnum_asc = 1 then status_time end) as initial_time,
       max(case when seqnum_desc = 1 then status end) as current_status,
       max(case when seqnum_desc = 1 then status_time end) as current_time
from (select t.*,
             row_number() over (partition by applicant_id order by status_time) as seqnum_asc,
             row_number() over (partition by applicant_id order by status_time desc) as seqnum_desc
      from t
     ) t
group by t.applicant_id;

データベースが をサポートしていない場合はrow_number()、読みやすくするために相関サブクエリをお勧めします。しかし、それらもネストされています。要件を満たすMySQLのソリューションは次のとおりです。

select t.applicant_id,
       substring_index(group_concat(status) separator ',' order by status_time), ',', 1) as initial_status,
       min(status_time) as initial_time,
       substring_index(group_concat(status) separator ',' order by status_time desc), ',', 1) as current_status,
       max(status_time) as current_time
from t
group by t.applicant_id;
于 2013-05-06T21:48:15.000 に答える
0
SELECT  a.application_id
        , a.application_status as initial_status
        , a.status_time as initial_time
        , b.application_status as current_status
        , b.status_time as current_status_time  
FROM        sample1 A
CROSS JOIN sample1  B
WHERE   A.application_status = 'received'
and b.  application_status = 'approved'
于 2013-05-06T22:23:03.800 に答える
0

1つのapplication_idに対して、「受信済み」ステータス用の1行と「承認済み」ステータス用の1行があると仮定すると(質問に記載されているように)、インラインビューを使用して問題を解決できます:

select section1.applicant_id AS applicant_id, 'received' AS initial_status, 
       section1.status_time AS initial_time, 'approved' AS current_status,
       section2.status_time AS current_status_time from    
   (select applicant_id, status_time from yourtable where application_status = 'received') section1,   
   (select applicant_id, status_time from yourtable where application_status = 'approved') section2 
   where section1.applicant_id = section2.applicant_id;
于 2013-05-06T21:53:29.293 に答える
0

MS SQL (Transact-SQL) であり、ソース テーブルの名前が [SourceTable] と適切であると仮定します。=)

SELECT DISTINCT
                [Probe].applicant_id,
                [LogMin].application_status     [initial_status], 
                [LogMin].status_time            [initial_time],
                [LogMax].application_status     [current_status], 
                [LogMax].status_time            [current_status_time]
FROM            (
                SELECT      MAX(status_time)    [MaxDate],
                            MIN(status_time)    [MinDate],
                            [applicant_id]
                FROM        [SourceTable]
                GROUP BY    [applicant_id]
                )           [Probe]
INNER JOIN      [SourceTable]                   [LogMax]
        ON      [Probe].[applicant_id]      =   [LogMax].[applicant_id]
        AND     [Probe].[MaxDate]           =   [LogMax].[status_time]
INNER JOIN      [SourceTable]                   [LogMin]
        ON      [Probe].[applicant_id]      =   [LogMin].[applicant_id]
        AND     [Probe].[MinDate]           =   [LogMin].[status_time]

SQLFiddle テストへのリンクはこちらです。

于 2013-05-06T22:10:42.807 に答える
0

このようなことを試してください。

select
    t1.applicant_id,
    t2.application_status initial_status,
    t1.initial_time,
    t3.application_status current_status,
    t1.current_status_time
from
    (select
          applicant_id,
          min(status_time) initial_time,
          max(status_time) current_status_time
    from
        your_table
    group by
         applicant_id) t1
    inner join your_table t2
        on (t1.applicant_id = t2.applicant_id and t1.initial_time = t2.status_time)
    inner join your_table t3
        on (t1.applicant_id = t3.applicant_id and t1.current_status_time = t3.status_time)
于 2013-05-07T02:23:08.967 に答える