繁体   English   中英

需要在同一列中获取具有min(date)和max(date)datavalue的数据值的id的最小和最大日期

[英]need to get the min and max date for an id with a datavalue for min(date) and max(date) datavalue in the same column

给定此数据:

ID      FirstDate       LastDate       ItemId
12A     05-11-2011      05-11-2011        0
12A     12-19-2011      12-19-2011        3
12A     01-04-2012      01-04-2012        3
12A     01-19-2012      01-19-2012       12
64B     06-15-2010      06-15-2010        0
64B     08-19-2011      08-19-2011        3

我想看看:

ID     FirstDate    FirstItemId     LastDate     LastItemId
12A    05-11-2011       0           01-19-2012       12
64B    06-15-2010       0           08-19-2011        3

您可以结合使用开窗功能来获得以下结果:

select id,
  max(case when FirstRowNumber= 1 then firstdate end) firstdate,
  max(case when FirstRowNumber= 1 then itemid end) firstitemId,
  max(case when LastRowNumber= 1 then lastdate end) lastdate,
  max(case when LastRowNumber= 1 then itemid end) lastitemId
from 
(
  select id, firstdate, lastdate, itemid,
    row_number() over(partition by id order by firstdate) FirstRowNumber,
    row_number() over(partition by id order by lastdate desc) LastRowNumber
  from yourtable
) x
where FirstRowNumber= 1
  or LastRowNumber= 1
group by id

请参阅带有演示的SQL Fiddle

此解决方案以ASC / DESC日期顺序将row_number分配给记录。 然后,您只需关心row_number = 1的记录。 然后,我对这些值应用了聚合和CASE语句,以获得正确的结果。

或者,您可以使用非常难看的UNPIVOTPIVOT解决方案:

select *
from 
(
  select id,
    val,
    case when firstrownumber = 1 and col = 'firstdate'
          then 'firstdate'
        when firstrownumber = 1 and col = 'itemid'
          then 'firstitemid'
        when LastRowNumber = 1 and col = 'lastdate'
          then 'lastdate'
        when LastRowNumber = 1 and col = 'itemid'
          then 'lastitemid'
        else '' end col
  from
  (
    select id, 
      convert(varchar(10), firstdate, 120) firstdate, 
      convert(varchar(10), lastdate, 120) lastdate, 
      cast(itemid as varchar(10)) itemid,
      row_number() over(partition by id order by firstdate) FirstRowNumber,
      row_number() over(partition by id order by lastdate desc) LastRowNumber
    from yourtable
  ) x
  unpivot
  (
    val for col in (firstdate, lastdate, itemid)
  ) u
) x1
pivot
(
  max(val)
  for col in ([firstdate], [firstitemid], 
              [lastdate], [lastitemid])
) p

参见带有演示的SQL Fiddle

在最基本的形式中,您可能希望将SQL mingroup by功能group by

select ID
    , min(FirstDate) as FirstDate
    , min(ItemId) as FirstItemId
    , max(LastDate) as LastDate
    , max(ItemId) as LastItemId
from MyTable
group by ID

但是请注意,除非数据碰巧是那样,否则这将返回每一列的绝对最小值和最大值,而不必返回与FirstDate等相对应的ItemId。 这是一种根据开始日期/最后日期获取ItemID的替代方法:

-- Get ItemIDs that correspond to First/Last Dates
select ID
    , FirstDate
    , (select min(ItemID) from Mytable where ID = a.ID and FirstDate = a.FirstDate) as FirstItemID
    , LastDate
    , (select max(ItemID) from Mytable where ID = a.ID and LastDate = a.LastDate) as LastItemID
from (
    select ID
        , min(FirstDate) as FirstDate
        , max(LastDate) as LastDate
    from Mytable
    group by ID
) as a

我发现关联的子查询通常比窗口函数更快(并且可能更易于理解),但是您必须在环境中使用数据进行测试。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM