Sql 需要获取id的最小和最大日期,该id的最小(日期)和最大(日期)数据值在同一列中

Sql 需要获取id的最小和最大日期,该id的最小(日期)和最大(日期)数据值在同一列中,sql,sql-server-2008,pivot,Sql,Sql Server 2008,Pivot,鉴于这些数据: 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

鉴于这些数据:

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
    , 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

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

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

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

此解决方案将行号分配给ASC/DESC日期顺序中的记录。那么您只关心行数=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只是结构化查询语言—一种被许多数据库系统使用的语言,但不是数据库产品。。。很多东西都是特定于供应商的-因此我们确实需要知道您使用的是什么数据库系统和哪个版本…我已经尝试过,并且只成功地获得了FirstItemId值:select ID,ItemId from select ItemId,ID,row_number over partition by ID order by MINFirstDate[rownum]from table1 group by ItemId,ID,FirstDate具有MINFirstDate=FirstDate a,其中rownum=1 order by ID,ItemId在SQL 2008中工作,我只能提取MINFirstDate的ItemId。从mytable1中选择ID,ItemId,rownum[rownum]从mytable1 group by ItemId,ID,FirstDate按MINFirstDate=FirstDate a选择ID,ItemId,rownum=1按ID排序,ItemId请参阅。这些解决方案对你有用吗?蓝脚怪也有很好的贡献。