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请参阅。这些解决方案对你有用吗?蓝脚怪也有很好的贡献。