0

鉴于此数据:

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
4

2 回答 2

1

您可以使用窗口函数的组合来获得此结果:

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

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

或者你可以使用一个非常丑陋的UNPIVOT解决PIVOT方案:

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

于 2012-10-08T18:40:35.637 回答
0

在它的最基本形式中,您可能希望将SQLmingroup 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

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

于 2012-10-08T18:18:22.657 回答