我如何构造我的 SQL 查询以 select DB2 table 中每个关键字段的两个 latest/most 最近记录组?
How can I construct my SQL query to select the two latest/most recent groups of records for each key field in a table in DB2?
给定一个数据集例如如下:
PERSON - 分配资金的人(关键字段)
EFFECTIVE DATE - 百分比分配的生效日期
RECIPIENT - 收到一定比例资金的人
PERCENTAGE - 此人收到的百分比
(因此对于任何给定的生效日期,一个人将总计 100% 分配给任何给定的接收者组合)
PERSON EFFECTIVE DATE RECIPIENT PERCENTAGE
---------- --------------- ------------- -----------
MONICA 2015-10-01 BARNEY 100% +
MONICA 2015-09-01 BARNEY 50% +
MONICA 2015-09-01 MARSHALL 20% +
MONICA 2015-09-01 LILY 30% +
MONICA 2015-08-01 ROBIN 50%
MONICA 2015-08-01 TED 50%
CHANDLER 2015-10-01 ROBIN 50% +
CHANDLER 2015-10-01 LILY 50% +
CHANDLER 2015-07-10 BARNEY 50% +
CHANDLER 2015-07-10 MARSHALL 50% +
CHANDLER 2015-06-01 ROBIN 50%
CHANDLER 2015-06-01 LILY 50%
CHANDLER 2015-04-10 BARNEY 50%
CHANDLER 2015-04-10 MARSHALL 50%
ROSS 2015-10-01 MARSHALL 100% +
ROSS 2015-09-15 BARNEY 100% +
PHOEBE 2015-10-01 MARSHALL 20% +
PHOEBE 2015-10-01 BARNEY 20% +
PHOEBE 2015-10-01 LILY 20% +
PHOEBE 2015-10-01 ROBIN 20% +
PHOEBE 2015-10-01 TED 20% +
PHOEBE 2015-09-01 MARSHALL 100% +
PHOEBE 2015-08-01 BARNEY 100%
PHOEBE 2015-07-01 LILY 100%
PHOEBE 2015-06-01 ROBIN 100%
PHOEBE 2015-05-01 TED 100%
我如何构建一个 SQL 查询,该查询一次只 return 每个人的两组最新分配(上面标有“+”的所有记录)?这样我就可以将数据处理成显示内容,例如:
"Monica changed allocation FROM 50% for Barney, 20% for Marshall, and 30% for Lily TO 100% for Barney."
"Chandler changed allocation FROM 50% for Barney, 50% for Marshall TO 50% for Robin, 50% for Lily."
"Ross changed allocation FROM 100% for Barney TO 100% for Marshall."
"Phoebe changed allocation FROM 100% for Marshall TO 20% for Marshall, 20% for Lily, 20% for Barney, 20% for Robin, 20% for Ted."
这是使用 where
的一种方法:
select t.*
from t
where t.effective_date in (select t2.effective_date
from t t2
where t2.person = t.person
group by t2.effective_date
order by t2.effective_date desc
fetch first 2 rows only
);
您也可以使用 dense_rank()
:
select t.*
from (select t.*,
dense_rank() over (partition by person order by effective_date desc) as seqnum
from t
) t
where seqnum <= 2;
可以这样试试
select *
from table as W
where w.effective_date >= (
//get 2nd max effective date
select max(a.effective_date) from table as a
where a.person = w.person
and a.effective_date Not = (
//get max of effective_date per person
select max(x.effective_date) from table as x
where x.person = a.person)
)
row_number是另一种选择
select t.*
from (select t.*,
row_number() over (partition by person order by effective_date desc) as seqnum
from t
) t
where seqnum <= 2;
给定一个数据集例如如下:
PERSON - 分配资金的人(关键字段)
EFFECTIVE DATE - 百分比分配的生效日期
RECIPIENT - 收到一定比例资金的人
PERCENTAGE - 此人收到的百分比
(因此对于任何给定的生效日期,一个人将总计 100% 分配给任何给定的接收者组合)
PERSON EFFECTIVE DATE RECIPIENT PERCENTAGE
---------- --------------- ------------- -----------
MONICA 2015-10-01 BARNEY 100% +
MONICA 2015-09-01 BARNEY 50% +
MONICA 2015-09-01 MARSHALL 20% +
MONICA 2015-09-01 LILY 30% +
MONICA 2015-08-01 ROBIN 50%
MONICA 2015-08-01 TED 50%
CHANDLER 2015-10-01 ROBIN 50% +
CHANDLER 2015-10-01 LILY 50% +
CHANDLER 2015-07-10 BARNEY 50% +
CHANDLER 2015-07-10 MARSHALL 50% +
CHANDLER 2015-06-01 ROBIN 50%
CHANDLER 2015-06-01 LILY 50%
CHANDLER 2015-04-10 BARNEY 50%
CHANDLER 2015-04-10 MARSHALL 50%
ROSS 2015-10-01 MARSHALL 100% +
ROSS 2015-09-15 BARNEY 100% +
PHOEBE 2015-10-01 MARSHALL 20% +
PHOEBE 2015-10-01 BARNEY 20% +
PHOEBE 2015-10-01 LILY 20% +
PHOEBE 2015-10-01 ROBIN 20% +
PHOEBE 2015-10-01 TED 20% +
PHOEBE 2015-09-01 MARSHALL 100% +
PHOEBE 2015-08-01 BARNEY 100%
PHOEBE 2015-07-01 LILY 100%
PHOEBE 2015-06-01 ROBIN 100%
PHOEBE 2015-05-01 TED 100%
我如何构建一个 SQL 查询,该查询一次只 return 每个人的两组最新分配(上面标有“+”的所有记录)?这样我就可以将数据处理成显示内容,例如:
"Monica changed allocation FROM 50% for Barney, 20% for Marshall, and 30% for Lily TO 100% for Barney."
"Chandler changed allocation FROM 50% for Barney, 50% for Marshall TO 50% for Robin, 50% for Lily."
"Ross changed allocation FROM 100% for Barney TO 100% for Marshall."
"Phoebe changed allocation FROM 100% for Marshall TO 20% for Marshall, 20% for Lily, 20% for Barney, 20% for Robin, 20% for Ted."
这是使用 where
的一种方法:
select t.*
from t
where t.effective_date in (select t2.effective_date
from t t2
where t2.person = t.person
group by t2.effective_date
order by t2.effective_date desc
fetch first 2 rows only
);
您也可以使用 dense_rank()
:
select t.*
from (select t.*,
dense_rank() over (partition by person order by effective_date desc) as seqnum
from t
) t
where seqnum <= 2;
可以这样试试
select *
from table as W
where w.effective_date >= (
//get 2nd max effective date
select max(a.effective_date) from table as a
where a.person = w.person
and a.effective_date Not = (
//get max of effective_date per person
select max(x.effective_date) from table as x
where x.person = a.person)
)
row_number是另一种选择
select t.*
from (select t.*,
row_number() over (partition by person order by effective_date desc) as seqnum
from t
) t
where seqnum <= 2;