-1

我有一张这样的桌子:

|    date   | example_variable |
| 2013-2-22 |       cat        |
| 2013-3-22 |       dog        |
| 2013-1-22 |       ewe        |
| 2013-8-22 |       pig        |

我已经知道该怎么做是:

SELECT
a.example_variable as V1,
b.example_variable as V2,
c.example_variable as V3, 
a.AsOfDate as 1stDate,     
b.AsOfDate as 2ndDate,
c.AsOfDate as 3rdDate
FROM <table> a, <table> b, <table> c
WHERE a.AsOfDate = '2013-1-22'
AND b.AsOfDate = '2013-2-22'
AND c.AsOfDate = '2013-3-22'

输出如下:

|   V1   |   V2   |   V3   |    1stDate   |    2ndDate   |    3rdDate   |
|  ewe   |   cat  |   dog  |  '2013-1-22' |  '2013-2-22' | '2013-3-22'  |

在上面的查询中,我手动输入了三个最近的日期。我想要那些自动找到的。似乎我可以使用顶部,但我不确定如何使用。


更复杂的版本:

我已经简化了上面的例子。在我的真实世界案例中,有多个具有相同日期的行,如下所示:

|    date   |      rank        | example_variable  |
| 2013-2-22 |      1           |       cat1        |
| 2013-2-22 |      2           |       cat2        |
| 2013-3-22 |      1           |       dog1        |
| 2013-3-22 |      2           |       dog2        |
| 2013-1-22 |      1           |       ewe1        |
| 2013-1-22 |      2           |       ewe2        |
| 2013-8-22 |      1           |       pig1        |
| 2013-8-22 |      2           |       pig2        |

查询是这样的:

SELECT
a.rank, b.rank, c.rank,
a.example_variable as V1,
b.example_variable as V2,
c.example_variable as V3, 
a.AsOfDate as 1stDate,     
b.AsOfDate as 2ndDate,
c.AsOfDate as 3rdDate
FROM <table> a, <table> b, <table> c
WHERE a.rank = b.rank,
And b.rank = c.rank,
AND a.AsOfDate = '2013-1-22'
AND b.AsOfDate = '2013-2-22'
AND c.AsOfDate = '2013-3-22'

带输出:

|  rank  |   V1    |   V2    |   V3    |    1stDate   |    2ndDate   |    3rdDate   |
|   1    |  ewe1   |   cat1  |   dog1  |  '2013-1-22' |  '2013-2-22' | '2013-3-22'  |
|   2    |  ewe2   |   cat2  |   dog2  |  '2013-1-22' |  '2013-2-22' | '2013-3-22'  |
4

1 回答 1

6

编辑 1:即使使用更复杂的数据版本,您也应该能够使用row_number()

select [rank],
  max(case when rn = 1 then example_variable end) as v1,
  max(case when rn = 2 then example_variable end) as v2,
  max(case when rn = 3 then example_variable end) as v3,
  max(case when rn = 1 then date end) as [1stDate],
  max(case when rn = 2 then date end) as [2ndDate],
  max(case when rn = 3 then date end) as [3rdDate]
from
(
  select date, [rank], example_variable,
    row_number() over(partition by [rank] order by date) rn
  from yt
) d
group by [rank];

演示

如果你没有,row_number你可以使用以下内容:

;with d1 as
(
  select t.date, t.[rank], t.example_variable
  from yt t
  inner join
  (
    select min(date) date, [rank]
    from yt
    group by [rank]
  ) d
    on t.date = d.date
    and t.[rank] = d.[rank]
)
select d1.rank,
  d1.example_variable v1,
  d2.example_variable v2,
  d3.example_variable v3,
  d1.date [1stDate],
  d2.date [2ndDate],
  d3.date [3rdDate]
from d1
cross apply
(
  select top 1 date, [rank], example_variable
  from yt t
  where d1.date < t.date
    and d1.[rank] = t.[rank]
) d2
cross apply
(
  select top 1 date, [rank], example_variable
  from yt t
  where d2.date < t.date
    and d2.[rank] = t.[rank]
) d3;

演示

您没有指定您使用的是什么数据库,但如果您使用的是支持窗口函数的数据库,那么您可以使用row_number()

select 
  max(case when rn = 1 then example_variable end) as v1,
  max(case when rn = 2 then example_variable end) as v2,
  max(case when rn = 3 then example_variable end) as v3,
  max(case when rn = 1 then date end) as [1stDate],
  max(case when rn = 2 then date end) as [2ndDate],
  max(case when rn = 3 then date end) as [3rdDate]
from
(
  select date, example_variable,
    row_number() over(order by date) rn
  from yt
) d;

请参阅SQL Fiddle with Demo

如果你没有,row_number那么你可以使用以下内容:

select d1.example_variable v1,
  d2.example_variable v2,
  d3.example_variable v3,
  d1.date [1stdate],
  d2.date [2nddate],
  d3.date [3rddate]
from
(
  select top 1 date, example_variable
  from yt
  order by date
) d1
cross apply
(
  select top 1 d2.date, d2.example_variable
  from yt d2
  where d1.date < d2.date
  order by d2.date
) d2
cross apply
(
  select top 1 d3.date, d3.example_variable
  from yt d3
  where d2.date < d3.date
  order by d3.date
) d3;

演示

于 2013-05-23T16:07:50.300 回答