鉴于下表包含示例行,我正在寻找一个查询,以提供对同一记录所做更改的汇总结果。所有更改都是针对另一个表(结果表)中的基本记录进行的,因此结果表的内容不是累积性的。
基本记录(从中进行所有更改)
突出显示已编辑的列
我正在寻找一个查询,该查询可以为我提供累积的更改(按日期顺序)。这将是结果行:
任何帮助表示赞赏!
更新---------------
让我澄清一下。被编辑的记录存在于一个表中,我们称其为[dbo]。[Base]。当某人从[dbo]。[Base]更新记录时,他的更新将进入[dbo]。[Updates]。因此,一个人总是从基表进行编辑。
在某个时刻,假设每天一次,我们需要使用以下规则来计算变化总和:
对于任何给定的记录,请确定每列的最新更改并进行最新更改。如果未对列进行任何更改,请从[dbo]。[Base]中获取值。因此,查看[dbo]。[Updates]表的一种方法是仅查看已更改的列。
请不要讨论这种方法的优点,我知道这很奇怪。我只需要弄清楚如何确定每个记录的最终状态。
谢谢!
答案 0 :(得分:1)
这很脏,但是您可以试一下(在这里进行测试:https://rextester.com/MKSBU15593)
我使用CTE对基本表和更新表进行初始CROSS JOIN
的操作,然后执行第二步将其过滤到仅ID匹配的行。从那里开始,我为每一列使用FIRST_VALUE()
,按ID值划分并按CASE表达式排序(如果Base列值与Update列值匹配,则为1,否则为0),以及Datemodified列以获取最新版本每列中的一个。
它吐出来
CREATE TABLE Base
(
ID INT
,FNAME VARCHAR(100)
,LNAME VARCHAR(100)
,ADDRESS VARCHAR(100)
,RATING INT
,[TYPE] VARCHAR(5)
,SUBTYPE VARCHAR(5)
);
INSERT INTO dbo.Base
VALUES
( 100,'John','Doe','123 First',3,'Emp','W2'),
( 200,'Jane','Smith','Wacker Dr.',2,'Emp','W2');
CREATE TABLE Updates
(
ID INT
,DATEMODIFIED DATE
,FNAME VARCHAR(100)
,LNAME VARCHAR(100)
,ADDRESS VARCHAR(100)
,RATING INT
,[TYPE] VARCHAR(5)
,SUBTYPE VARCHAR(5)
);
INSERT INTO dbo.Updates
VALUES
( 100,'1/15/2019','John','Doe','123 First St.',3,'Emp','W2'),
( 200,'1/15/2019','Jane','Smyth','Wacker Dr.',2,'Emp','W2'),
( 100,'1/17/2019','Johnny','Doe','123 First',3,'Emp','W2'),
( 200,'1/19/2019','Jane','Smith','2 Wacker Dr.',2,'Emp','W2'),
( 100,'1/20/2019','Jon','Doe','123 First',3,'Cont','W2');
WITH merged AS
(
SELECT b.ID AS IDOrigin
,'1/1/1900' AS DATEMODIFIEDOrigin
,b.FNAME AS FNAMEOrigin
,b.LNAME AS LNAMEOrigin
,b.ADDRESS AS ADDRESSOrigin
,b.RATING AS RATINGOrigin
,b.[TYPE] AS TYPEOrigin
,b.SUBTYPE AS SUBTYPEOrigin
,u.*
FROM base b
CROSS JOIN
dbo.Updates u
), filtered AS
(
SELECT *
FROM merged
WHERE IDOrigin = ID
)
SELECT distinct
ID
,FNAME = FIRST_VALUE(FNAME) OVER (PARTITION BY ID ORDER BY CASE WHEN FNAME = FNAMEOrigin THEN 1 ELSE 0 end, datemodified desc)
,LNAME = FIRST_VALUE(LNAME) OVER (PARTITION BY ID ORDER BY CASE WHEN LNAME = LNAMEOrigin THEN 1 ELSE 0 end, datemodified desc)
,ADDRESS = FIRST_VALUE(ADDRESS) OVER (PARTITION BY ID ORDER BY CASE WHEN ADDRESS = ADDRESSOrigin THEN 1 ELSE 0 end, datemodified desc)
,RATING = FIRST_VALUE(RATING) OVER (PARTITION BY ID ORDER BY CASE WHEN RATING = RATINGOrigin THEN 1 ELSE 0 end, datemodified desc)
,[TYPE] = FIRST_VALUE([TYPE]) OVER (PARTITION BY ID ORDER BY CASE WHEN [TYPE] = TYPEOrigin THEN 1 ELSE 0 end, datemodified desc)
,SUBTYPE = FIRST_VALUE(SUBTYPE) OVER (PARTITION BY ID ORDER BY CASE WHEN SUBTYPE = SUBTYPEOrigin THEN 1 ELSE 0 end, datemodified desc)
FROM filtered
答案 1 :(得分:0)
您不只想要最后一条记录吗?
select e.*
from edited e
where e.datemodified = (select max(e2.datemodified)
from edited e2
where e2.id = e.id
);