我有一个包含以下字段的Rep表:
RepNbr可能会有变化。我需要编写一个查询,显示每个有效日期的repnbr。什么是repnbr先前和当有变化时。所以,我试图在10月21日拉动M258的复制品(什么是repnbr先前),6月3日16日DM25的复制品以及M258的复制品是在6/8/16。
我尝试了以下查询:此查询仅提取6/3和6/8的有效日期,并且不会回顾之前的repnbr。
;with t1 as
(
select
acctnbr,
repnbr,
effectivedate,
rn = row_number() over (partition by repnbr order by acctnbr)
from
reptable
where
acctnbr = '123'
)
select
*
from
t1
where
rn = '1'
order by
effectivedate
结果:
我的输出应该如下:
我的查询错误是什么? 谢谢,
答案 0 :(得分:2)
用于SQL 2012 +
的USELAG()
和/或LEAD()
函数
DECLARE @Rep AS TABLE (Acct INt, RepNbr CHAR(4), EffectiveDate DATETIME)
INSERT INTO @Rep VALUES
(123,'M258','2015-10-15')
,(123,'M258','2015-10-21')
,(123,'DM25','2015-06-03')
,(123,'M258','2015-06-08')
;WITH cte AS (
SELECT *
,LAG(RepNbr) OVER (PARTITION BY Acct ORDER BY EffectiveDate) as PrevRepNbr
FROM
@Rep
)
SELECT Acct, RepNbr, EffectiveDate
FROM
cte
WHERE
PrevRepNbr IS NULL
OR PrevRepNbr <> RepNbr
请注意,您的示例不是生效日期的顺序,因此您的结果将不会如您所述。因为10-21是在6-3之后......
Acct RepNbr EffectiveDate
123 DM25 2015-06-03 00:00:00.000
123 M258 2015-06-08 00:00:00.000
123 M258 2015-10-15 00:00:00.000
123 M258 2015-10-21 00:00:00.000
这意味着RepNbr仅在6/8从DM25变为M258
如果您将示例表更改为:
DECLARE @Rep AS TABLE (Acct INt, RepNbr CHAR(4), EffectiveDate DATETIME)
INSERT INTO @Rep VALUES
(123,'M258','2015-06-03')
,(123,'M258','2015-06-08')
,(123,'DM25','2015-10-15')
,(123,'M258','2015-10-21')
然后它开始于10月15日6/3更改为DM25的M258,然后在10月21日更改回M258。
如果您不想查看原始/起始值,请删除WHERE PrevRepNbr IS NULL
不使用@Rep进行编辑:
;WITH cte AS (
SELECT
Acct
,RepNbr
,EffectiveDate
,LAG(RepNbr) OVER (PARTITION BY Acct ORDER BY EffectiveDate) as PrevRepNbr
FROM
TableName
)
SELECT Acct, RepNbr, EffectiveDate
FROM
cte
WHERE
PrevRepNbr IS NULL
OR PrevRepNbr <> RepNbr
答案 1 :(得分:2)
较旧的Sql sever版本分组
DECLARE @Rep AS TABLE (Acctnbr int, RepNbr CHAR(4), EffectiveDate DATETIME)
INSERT INTO @Rep VALUES
(123,'M258','2015-10-15')
,(123,'M258','2015-10-21')
,(123,'DM25','2015-06-08')
,(123,'M258','2015-06-03');
WITH cte AS (
select *,
grp = row_number() over(partition by acctnbr order by effectivedate)
- row_number() over(partition by acctnbr, RepNbr order by effectivedate)
from @rep
)
SELECT acctnbr, RepNbr, max(effectivedate) effectivedate
from cte
group by acctnbr, RepNbr, grp
order by acctnbr, max(effectivedate) desc;