簡體   English   中英

SQL查詢 - 從同一行中的一個表打印最小值和最大值

[英]SQL query - print the min and max from one table in the same row

我需要一些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

我怎么能完成這樣的事情,最好只使用連接而不是嵌套選擇?

您沒有說明您的數據庫產品,但您可以在任何數據庫上使用類似的東西:

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 with Demo

一般來說,解決此問題的最佳方法是使用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;

假設對於一個applicant_id,您有一行“已收到”狀態,另一行有“已批准”狀態(如您在問題中列出的那樣),您可以使用內聯視圖來解決您的問題:

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;

假設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測試就在這里

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'

嘗試這樣的事情。

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)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM