我有一张表,上面有这样的数据:
CREATE TABLE Test
(CustName varchar(20), Country varchar(20), RecordedTime datetime, CurrNo tinyint);
INSERT INTO Test
(CustName, Country, RecordedTime, CurrNo)
VALUES
('Alex', 'Australia', '2018-06-01 08:00:00', 1),
('Alex', 'China', '2018-06-01 10:00:00', 2),
('Alex', 'India', '2018-06-01 10:05:00', 3),
('Alex', 'Japan', '2018-06-01 11:00:00', 4),
('John', 'Australia', '2018-06-01 08:00:00', 1),
('John', 'China', '2018-06-02 08:00:00', 2),
('Bob', 'Australia', '2018-06-02 09:00:00', 1),
('Bob', 'Brazil', '2018-06-03 09:50:00', 2),
('Bob', 'Africa', '2018-06-03 11:50:00', 3),
('Bob', 'India', '2018-06-03 11:55:00', 4),
('Tim', 'Brazil', '2018-06-10 00:00:00', 2),
('Tim', 'Cuba', '2018-06-11 00:00:00', 3),
('Tim', 'India', '2018-06-11 00:05:00', 4),
('Jerry', 'Cuba', '2018-06-12 00:00:00', 4),
('Jerry', 'Brazil', '2018-06-12 00:05:00', 5),
('Jerry', 'India', '2018-06-12 00:10:00', 7),
('Jerry', 'USA', '2018-06-12 00:15:00', 9)
('Maulik', 'Aus', '2018-06-12 00:00:00',3),
('Maulik', 'Eng', '2018-06-13 00:00:00',4),
('Maulik', 'USA', '2018-06-14 00:00:00',5),
('Maulik', 'Ind', '2018-06-14 00:00:00',6);
表结果:
CustName Country RecordedTime CurrNo
-----------------------------------------------------
Alex Australia 2018-Jun-01 08:00 AM 1
Alex China 2018-Jun-01 10:00 AM 2
Alex India 2018-Jun-01 10:05 AM 3
Alex Japan 2018-Jun-01 11:00 AM 4
John Australia 2018-Jun-01 08:00 AM 1
John China 2018-Jun-02 08:00 AM 2
Bob Australia 2018-Jun-02 09:00 AM 1
Bob Brazil 2018-Jun-03 09:50 AM 2
Bob Africa 2018-Jun-03 11:50 AM 3
Bob India 2018-Jun-03 11:55 AM 4
Tim Brazil 2018-Jun-10 12:00 AM 2
Tim Cuba 2018-Jun-11 12:00 AM 3
Tim India 2018-Jun-11 12:05 AM 4
Jerry Cuba 2018-Jun-12 12:00 AM 4
Jerry Brazil 2018-Jun-12 12:05 AM 5
Jerry India 2018-Jun-12 12:10 AM 7
Jerry USA 2018-Jun-12 12:15 AM 9
Maulik Aus 2018-Jun-12 00:00:AM 3
Maulik Eng 2018-Jun-13 00:00:AM 4
Maulik USA 2018-Jun-14 00:00:AM 5
Maulik Ind 2018-Jun-14 00:00:AM 6
我需要涵盖以下所有情况的输出。
对于如何在“审核”和“历史记录”字段中显示值,存在一条经验法则;
记录应仅对原始帐户具有Audit =“ ADD”或“ CHANGE”,并且History =“ NEW”,“ BEFORE”或“ CURRENT”(这意味着表中的条目必定是从CurrNo = 1开始
记录中不应包含Audit =“ ADD”和History =“ NEW” 对于迁移的帐户(这意味着表中的条目不是从CurrNo = 1开始,它可能从2或3或任何升序数字开始),对于这种类型的帐户,审计应具有“ CHANGE”和历史记录字段应具有“ BEFORE”或“ CURRENT”
场景1 : 如果输入日期为2018年6月1日,则输出应如下所示(即,当同一天多次添加和修改记录时)
CustName Country RecordedTime Audit History
----------------------------------------------------------------
Alex Australia 2018-Jun-01 08:00 AM ADD NEW
Alex Australia 2018-Jun-01 08:00 AM CHANGE BEFORE
Alex Japan 2018-Jun-01 11:00 AM CHANGE CURRENT
John Australia 2018-Jun-01 08:00 AM ADD NEW
场景2 : 如果给定输入日期为2018年6月2日,则输出应如下所示(即,当前几天已经有一条记录并且今天编辑了同一条记录并且今天有任何新记录时)
CustName Country RecordedTime Audit History
-----------------------------------------------------------------
John Australia 2018-Jun-01 08:00 AM CHANGE BEFORE
John China 2018-Jun-02 08:00 AM CHANGE CURRENT
Bob Australia 2018-Jun-02 09:00 AM ADD NEW
场景3 : 如果给定输入日期为2018年6月3日,则输出应如下所示(即,当同一天对记录进行多次编辑时,它应列出最新日期的最后一条记录,然后列出当前给定日期的最后一条记录)
CustName Country RecordedTime Audit History
----------------------------------------------------------------
Bob Australia 2018-Jun-02 09:00 AM CHANGE BEFORE
Bob India 2018-Jun-03 12:55 AM CHANGE CURRENT
场景4 : 如果输入日期为2018年6月10日,则输出应为以下
CustName Country RecordedTime Audit History
----------------------------------------------------------------
Tim Brazil 2018-Jun-10 12:00 AM CHANGE CURRENT
场景5 : 如果输入日期为2018年6月11日,则输出应如下所示(即类似于方案2)
CustName Country RecordedTime Audit History
----------------------------------------------------------------
Tim Brazil 2018-Jun-10 12:00 AM CHANGE BEFORE
Tim India 2018-Jun-11 12:05 AM CHANGE CURRENT
场景6 : 如果输入日期为2018年6月12日,则输出应如下所示(即类似于方案3)
CustName Country RecordedTime Audit History
----------------------------------------------------------------
Jerry Cuba 2018-Jun-12 12:00 AM CHANGE BEFORE
Jerry USA 2018-Jun-12 12:15 AM CHANGE CURRENT
Maulik Aus 2018-Jun-12 00:00 AM CHANGE CURRENT
如果输入日期为2018年6月13日,则输出应如下所示
CustName Country RecordedTime Audit History
----------------------------------------------------------------
Maulik Aus 2018-Jun-12 00:00 AM CHANGE BEFORE
Maulik Eng 2018-Jun-13 00:00 AM CHANGE CURRENT
如果输入日期为2018年6月14日,则输出应如下所示
CustName Country RecordedTime Audit History
----------------------------------------------------------------
Maulik Eng 2018-Jun-13 00:00 AM CHANGE BEFORE
Maulik Ind 2018-Jun-14 00:00 AM CHANGE CURRENT
下面是我正在使用的当前代码(满足方案2和3,但不满足其余部分);
declare @d date='2018-Jun-03'
; with Indexer as
(
select
*,
rn= row_number() over(partition by CustName order by RecordedTime),
rn2=row_number() over(partition by CustName order by RecordedTime desc)
from records
)
,GetValidCustomerRecords as
(
select
CustName,
Country,
RecordedTime,
Audit = case when cast(RecordedTime as date)=@d and rn=1 then 'add' else 'change' end,
History = case
when cast(RecordedTime as date)=@d and rn=1
then 'new'
when cast(RecordedTime as date)<@d and rn=1
then 'before'
else 'current' end
from Indexer i
where CustName in
(
select
distinct CustName
from records
where cast(RecordedTime as date)=@d
)
and (rn=1 or rn2=1) and cast(RecordedTime as date)<=@d
)
select * from GetValidCustomerRecords
order by CustName, RecordedTime
任何SQL专家都可以修改此查询以满足所有情况?非常感谢和感谢。
注意:这里有一个类似的问题仅供参考-How to retrieve data from SQL Server based on below example?
答案 0 :(得分:1)
根据我的理解,以下是您所需输出的逻辑
第1步
第2步
第3步
第4步
第5步
-
CREATE TABLE #Test
(CustName varchar(20), Country varchar(20), RecordedTime datetime, CurrNo tinyint);
INSERT INTO #Test
(CustName, Country, RecordedTime, CurrNo)
VALUES
('Alex', 'Australia', '2018-06-01 08:00:00', 1),
('Alex', 'China', '2018-06-01 10:00:00', 2),
('Alex', 'India', '2018-06-01 10:05:00', 3),
('Alex', 'Japan', '2018-06-01 11:00:00', 4),
('John', 'Australia', '2018-06-01 08:00:00', 1),
('John', 'China', '2018-06-02 08:00:00', 2),
('Bob', 'Australia', '2018-06-02 09:00:00', 1),
('Bob', 'Brazil', '2018-06-03 09:50:00', 2),
('Bob', 'Africa', '2018-06-03 11:50:00', 3),
('Bob', 'India', '2018-06-03 00:55:00', 4),
('Tim', 'Brazil', '2018-06-10 00:00:00', 2),
('Tim', 'Cuba', '2018-06-11 00:00:00', 3),
('Tim', 'India', '2018-06-11 00:05:00', 4),
('Jerry', 'Cuba', '2018-06-12 00:00:00', 4),
('Jerry', 'Brazil', '2018-06-12 00:05:00', 5),
('Jerry', 'India', '2018-06-12 00:10:00', 7),
('Jerry', 'USA', '2018-06-12 00:15:00', 9),
('Maulik', 'Aus', '2018-06-12 00:00:00',3),
('Maulik', 'Eng', '2018-06-13 00:00:00',4),
('Maulik', 'USA', '2018-06-14 00:00:00',5),
('Maulik', 'Ind', '2018-06-14 00:00:00',6);
select * from #Test
declare @selectedDate date='2018-06-14';
with cte as
(
select CustName,max(CurrNo) maxno,count(1) cnt
from #Test where datediff(day,RecordedTime,@selectedDate)=0
group by CustName
),cte2 as (
select top 1 t.*,cnt
from #Test t join cte c on c.CustName =t.CustName
where datediff(day,RecordedTime,@selectedDate)>0 and t.CurrNo!=c.maxno
order by t.RecordedTime desc
union select top 1 t.*,cnt
from #Test t join cte c on c.CustName =t.CustName
where datediff(day,RecordedTime,@selectedDate)=0 and t.CurrNo!=c.maxno
order by t.RecordedTime
)
select t.CustName,t.Country,t.RecordedTime,cnt
,case when t.CurrNo=1 then 'ADD' else 'CHANGE' End as Audit
,case when t.CurrNo=1 then 'NEW' when t.CurrNo=c.maxno then 'CURRENT' else 'BEFORE' end History
from #Test t join cte c on c.CustName =t.CustName
where datediff(day,RecordedTime,@selectedDate)=0 and (t.CurrNo=c.maxno or t.CurrNo=1)
union
select top 1 t.CustName,t.Country,t.RecordedTime,cnt
,'CHANGE' Audit
,'BEFORE' History
from #Test t join cte c on c.CustName =t.CustName
where datediff(day,RecordedTime,@selectedDate)=0 and t.CurrNo=1 and c.cnt>1
union
select top 1 t.CustName,t.Country,t.RecordedTime,cnt
,'CHANGE' Audit
,'BEFORE' History
from cte2 t order by RecordedTime
drop table #Test
“ Ronen Ariely”的观点很不错。下面是更新的查询,它具有2次表扫描而不是8次表扫描。
with cte as
(
select CustName,max(CurrNo) maxno,count(1) cnt
from #Test where datediff(day,RecordedTime,@selectedDate)=0
group by CustName
),cte2 as (
select * from #Test where CustName in
(
select distinct custname from cte
)
and datediff(day,RecordedTime,@selectedDate)>=0
),cte3 as (
select top 1 t.*,cnt
from cte2 t join cte c on c.CustName =t.CustName
where datediff(day,RecordedTime,@selectedDate)>0 and t.CurrNo!=c.maxno
order by t.RecordedTime desc
union select top 1 t.*,cnt
from cte2 t join cte c on c.CustName =t.CustName
where datediff(day,RecordedTime,@selectedDate)=0 and t.CurrNo!=c.maxno
order by t.RecordedTime
)
select t.CustName,t.Country,t.RecordedTime
,case when t.CurrNo=1 then 'ADD' else 'CHANGE' End as Audit
,case when t.CurrNo=1 then 'NEW' when t.CurrNo=c.maxno then 'CURRENT' else 'BEFORE' end History
from cte2 t join cte c on c.CustName =t.CustName
where datediff(day,RecordedTime,@selectedDate)=0 and (t.CurrNo=c.maxno or t.CurrNo=1)
union
select top 1 t.CustName,t.Country,t.RecordedTime
,'CHANGE' Audit
,'BEFORE' History
from cte2 t join cte c on c.CustName =t.CustName
where datediff(day,RecordedTime,@selectedDate)=0 and t.CurrNo=1 and c.cnt>1
union
select top 1 t.CustName,t.Country,t.RecordedTime
,'CHANGE' Audit
,'BEFORE' History
from cte3 t order by RecordedTime
答案 1 :(得分:1)
据我从不同场景所了解的,它们基本上只能通过2条规则来实现。
有了一些窗口函数和外部查询中的OR,我们可以有两个规则来定位所有场景。
然后使用CASE WHEN
计算“审计”和“历史”。
SELECT
CustName, Country,
FORMAT(RecordedTime, 'yyyy-MMM-dd hh:mm tt') as RecordedTime,
(CASE CurrNo
WHEN 1 then 'ADD'
ELSE 'CHANGE'
END) as [Audit],
(CASE
WHEN CurrNo = 1 then 'NEW'
WHEN ReverseCurrRN = 1 then 'CURRENT'
ELSE 'BEFORE'
END) as [History]
--, CurrNo, ReverseCurrRN, MinCurrNoPerCust, MaxCurrNoPerCustDate ,MinCurrNoPerCust, MinDatePerCust, MaxDatePerCust
FROM
(
SELECT CustName, Country, RecordedTime, CurrNo
,ROW_NUMBER() OVER (PARTITION BY CustName ORDER BY CurrNo DESC) AS ReverseCurrRN
,MIN(CurrNo) OVER (PARTITION BY CustName) AS MinCurrNoPerCust
,MAX(CurrNo) OVER (PARTITION BY CustName, cast(RecordedTime AS DATE)) AS MaxCurrNoPerCustDate
,CAST(MIN(RecordedTime) OVER (PARTITION BY CustName) AS DATE) AS MinDatePerCust
,CAST(MAX(RecordedTime) OVER (PARTITION BY CustName) AS DATE) AS MaxDatePerCust
FROM Test t
WHERE CAST(RecordedTime AS DATE) between DATEADD(day,-1,@Date) and @Date
) q
WHERE MaxDatePerCust = @Date
AND (
-- Scenario 1 & 2 & 4 & 6
(MinDatePerCust = MaxDatePerCust AND (ReverseCurrRN = 1 OR CurrNo = MinCurrNoPerCust OR (MinCurrNoPerCust = 1 AND ReverseCurrRN = 2)))
-- Scenario 2 & 3 & 5 & 7 & 8
OR (MinDatePerCust != MaxDatePerCust AND (ReverseCurrRN = 1 OR CurrNo = 1 OR CurrNo = MaxCurrNoPerCustDate))
)
ORDER BY MinDatePerCust, CustName, CurrNo;
您可以在 db <> fiddle here
上对其进行测试答案 2 :(得分:1)
美好的一天,
请检查以下解决方案是否满足您的所有需求。我用您的数据和更多的行对其进行了测试,但是始终最好重新检查一次。乍一看,它似乎返回了请求的结果。稍后我会添加一些解释
我正在使用它的查询:
DECLARE @Date DATE = '2018-06-12';
with MyCTE as (
SELECT
t.CustName,t.Country,t.RecordedTime,t.CurrNo, D = CONVERT(DATE, RecordedTime)
,RN_D = ROW_NUMBER()
OVER (partition by t.CustName order by t.CurrNo desc)
,RN = ROW_NUMBER()
OVER (partition by t.CustName order by t.CurrNo)
,RN_Old = ROW_NUMBER()
OVER (partition by t.CustName, (CASE WHEN CONVERT(DATE, RecordedTime) < @Date then 0 else 1 END) order by t.CurrNo desc)
,Cnt = COUNT(*)
OVER (partition by t.CustName)
,CntToday = COUNT(CASE WHEN CONVERT(DATE, RecordedTime) = @Date THEN 1 ELSE NULL END)
OVER (partition by t.CustName)
FROM Test t
where
-- returns rows untill current date
CONVERT (DATE, RecordedTime) <= @Date
-- only if relevnat to current date
and EXISTS (
SELECT * FROM test t0
where CONVERT (DATE, RecordedTime) = @Date and t0.CustName = t.CustName
)
)
,MyCTE2 as (
select
CustName, Country, RecordedTime, D, CurrNo, RN_D, RN, Cnt, t2.c, History, CntToday, RN_Old
from MyCTE t1
left JOIN (select * from (values(1, 'NEW'),(1, 'BEFORE')) t2(c, History) ) t2
on t1.CurrNo = t2.c
and CntToday > 1
and D = @Date
where
RN_D = 1
or (RN = 1 and D = @Date)
or (RN_Old = 1 and D < @Date)
)
,MyCTE3 as (
select CustName, Country, RecordedTime
-- unmarke the bellow comment in order to get the accessories columns I used
-- This is recommended to understand the line-of-thinking
--, D, c, RN_D, RN, CurrNo, Cnt, CntToday, RN_Old
, History = CASE
WHEN CurrNo = 1 and Cnt = 1 then 'NEW'
WHEN RN_D = 1 then 'CURRENT'
else ISNULL(History,'BEFORE')
END
from MyCTE2
)
select CustName, Country, RecordedTime--, D, c, RN_D, RN, CurrNo, Cnt, CntToday, RN_Old
,Audit = CASE when History='New' then 'ADD' else 'CHANGE' END
, History
from MyCTE3
为了简化测试,我将整个查询插入表函数
DROP FUNCTION IF EXISTS dbo.F
GO
CREATE FUNCTION dbo.F(@Date DATE)
RETURNS TABLE AS RETURN (
--DECLARE @Date DATE = '2018-06-12';
with MyCTE as (
SELECT
t.CustName,t.Country,t.RecordedTime,t.CurrNo, D = CONVERT(DATE, RecordedTime)
,RN_D = ROW_NUMBER()
OVER (partition by t.CustName order by t.CurrNo desc)
,RN = ROW_NUMBER()
OVER (partition by t.CustName order by t.CurrNo)
,RN_Old = ROW_NUMBER()
OVER (partition by t.CustName, (CASE WHEN CONVERT(DATE, RecordedTime) < @Date then 0 else 1 END) order by t.CurrNo desc)
,Cnt = COUNT(*)
OVER (partition by t.CustName)
,CntToday = COUNT(CASE WHEN CONVERT(DATE, RecordedTime) = @Date THEN 1 ELSE NULL END)
OVER (partition by t.CustName)
FROM Test t
where
-- returns rows untill current date
CONVERT (DATE, RecordedTime) <= @Date
-- only if relevnat to current date
and EXISTS (
SELECT * FROM test t0
where CONVERT (DATE, RecordedTime) = @Date and t0.CustName = t.CustName
)
)
,MyCTE2 as (
select
CustName, Country, RecordedTime, D, CurrNo, RN_D, RN, Cnt, t2.c, History, CntToday, RN_Old
from MyCTE t1
left JOIN (select * from (values(1, 'NEW'),(1, 'BEFORE')) t2(c, History) ) t2
on t1.CurrNo = t2.c
and CntToday > 1
and D = @Date
where
RN_D = 1
or (RN = 1 and D = @Date)
or (RN_Old = 1 and D < @Date)
)
,MyCTE3 as (
select CustName, Country, RecordedTime
-- unmarke the bellow comment in order to get the accessories columns I used
-- This is recommended to understand the line-of-thinking
--, D, c, RN_D, RN, CurrNo, Cnt, CntToday, RN_Old
, History = CASE
WHEN CurrNo = 1 and Cnt = 1 then 'NEW'
WHEN RN_D = 1 then 'CURRENT'
else ISNULL(History,'BEFORE')
END
from MyCTE2
)
select CustName, Country, RecordedTime--, D, c, RN_D, RN, CurrNo, Cnt, CntToday, RN_Old
,Audit = CASE when History='New' then 'ADD' else 'CHANGE' END
, History
from MyCTE3
--order by CustName, RecordedTime
)
GO
使用该函数可以更轻松地进行多次测试,但是可能在生产中您将需要使用直接查询
-- Test
select * from F('2018-06-01') order by CustName , RecordedTime
select * from F('2018-06-02') order by CustName , RecordedTime
select * from F('2018-06-03') order by CustName , RecordedTime
select * from F('2018-06-10') order by CustName , RecordedTime
select * from F('2018-06-11') order by CustName , RecordedTime
select * from F('2018-06-12') order by CustName , RecordedTime
select * from F('2018-06-13') order by CustName , RecordedTime
select * from F('2018-06-14') order by CustName , RecordedTime
/ ****************更新于2018-08-19 14:05以色列时间**************** / < / p>
我注意到,为了参与线程,需要添加一些其他信息很重要。我希望这会有用
注意!在Microsoft SQL Server 2017开发人员版上测试
首先,让我们根据三个查询的执行计划来比较资源使用的百分比:(1)我的解决方案,(2)更新第一个解决方案后的(maulik kansara秒解决方案),和(3)maulik kansara第一个解决方案
现在让我们检查maulik kansara秒解决方案的EP图像:
此查询扫描表11次!
** 重要! EP不是建议我们选择哪个查询的唯一参数,但这可能是我们应该检查的第一个信息。此外,我们应该检查IO统计信息和时间统计信息,以及更多...
信用:该图像是使用sendryone工具拍摄的。有一个免费版本可以提供大多数DBA所需的内容。我正在使用作为Microsoft MVP免费获得的完整版本,所以谢谢;-)
答案 3 :(得分:1)
您在最初的请求中有很多if / and / buts,但也许有一个ALTERNATE VIEW数据可能是一个更好的解决方案,您只是没有想到或已经提供过,所以我会的。
为什么有单独的行同时显示前后,为什么不在返回的一行上显示。如果没有变化,为什么要显示?也许这是以后的问题。
要获得解决方案,我从测试数据中获取了一个简单的WITH,该数据用作查询的基准。您有自己的CurrNo,该CurrNo可能不会始终以1开头,甚至可能由于偶然而跳过序列号。因此,我的WITH声明由客户获取并由CurrNo排序的连续行号。即使CurrNo值可能是5、8、9、11(夸大的起始号和意外跳过的值),这也将始终按客户第1、2、3、4行返回。您甚至可以将订单更改为RecordedTime,以确保基于每个客户活动的DATE进行记录。
;with baseData as
(
select
T.*,
ROW_NUMBER() OVER (PARTITION BY CustName ORDER BY CurrNo) AS CustOrder
from
Test T
)
现在,使用查询。我有第一张表,这是查找系统中任何“更改”的基础。您将始终从这些记录开始。根据需要应用日期限制过滤器。无论行号是PLUS ONE还是相同基准数据的NEXT,LEFT-JOIN都将始终位于客户名PLUS上。因此,如果仅从您的数据中查看客户Alex和Jerry,您将获得以下
Customer Country Time CurrNo CustOrder
Alex Australia 2018-06-01 08:00:00 1 1
Alex China 2018-06-01 10:00:00 2 2
Alex India 2018-06-01 10:05:00 3 3
Alex Japan 2018-06-01 11:00:00 4 4
Jerry Cuba 2018-06-12 00:00:00 4 1
Jerry Brazil 2018-06-12 00:05:00 5 2
Jerry India 2018-06-12 00:10:00 7 3
Jerry USA 2018-06-12 00:15:00 9 4
因此您可以看到每个之间的自然行号归一化。所以现在,我的左联接是由客户和CustOrder列组成的,它不会跳过空白,因此我将获得类似
的记录Customer CustOrder NextCustOrder CurrNo NextCurrNo
Alex 1 2 1 1
Alex 2 3 2 2
Alex 3 4 3 3
Alex 4 (no 5th record) 4 4
Jerry 1 2 4 5
Jerry 2 3 5 7
Jerry 3 4 7 9
Jerry 4 (no 5th record) 9 (no next record)
最后,我将从始终存在的第一个记录中获取数据,如果存在对应的NEXT记录,它将显示新的已更改的TO值。该下一条记录将是下一行,并且可能会更改TO值,依此类推。
select
bd.CustName,
case when bd.CurrNo = 1 then 'ADD' else 'CHANGE' end as Audit,
bd.Country as CurrentValue,
bd.RecordedTime,
bdNext.Country as ChangedValue,
bdNext.RecordedTime ChangedTime,
bd.CurrNo,
bd.CustOrder
from
baseData bd
LEFT JOIN baseData bdNext
on bd.CustName = bdNext.CustName
AND bd.CustOrder +1 = bdNext.CustOrder;
CustName Audit CurrentValue RecordedTime ChangedValue ChangedTime CurrNo CustOrder
Alex ADD Australia 2018-06-01 08:00:00.000 China 2018-06-01 10:00:00.000 1 1
Alex CHANGE China 2018-06-01 10:00:00.000 India 2018-06-01 10:05:00.000 2 2
Alex CHANGE India 2018-06-01 10:05:00.000 Japan 2018-06-01 11:00:00.000 3 3
Alex CHANGE Japan 2018-06-01 11:00:00.000 NULL NULL 4 4
Jerry CHANGE Cuba 2018-06-12 00:00:00.000 Brazil 2018-06-12 00:05:00.000 4 1
Jerry CHANGE Brazil 2018-06-12 00:05:00.000 India 2018-06-12 00:10:00.000 5 2
Jerry CHANGE India 2018-06-12 00:10:00.000 USA 2018-06-12 00:15:00.000 7 3
Jerry CHANGE USA 2018-06-12 00:15:00.000 NULL NULL 9 4
如果您不希望记录的“最后一个值”是因为之后没有更改,只需将LEFT JOIN更改为INNER JOIN即可保证之后的内容有所更改。但是,如果您想查看所有新的“ ADD”记录而不进行更改,那将失败。您可以将其用作where子句,例如
where
bd.CurrNo = 1
OR bdNext.CustOrder IS NOT NULL
此外,您可以添加日期过滤器,例如
where
bd.RecordedTime >= '2018-06-10'
AND ( bd.CurrNo = 1
OR bdNext.CustOrder IS NOT NULL )
Ronen Ariely在评论中建议,上述带有日期的WHERE子句将应用于WITH baseData作为组件,并添加
where
T.RecordedTime >= '2018-06-10'
在数据进入其余联接活动之前对其进行预过滤