我有一个包含两个ID字段的数据库,一个由系统指定为GUID,一个ExternalID,用于表示数据清理后的重复项,该表还包含一个ModifiedDate
我正在尝试合并这些记录,最近修改的记录吸收旧帐户。我尝试了以下查询类型。
SELECT
a1.GUID
,a1.ModifiedDate
,a2.GUID
,a2,ModifiedDate
FROM Accounts a1
INNER JOIN Accounts a2 on a1.ExternalID = a2.ExternalID
不幸的是,这导致重复的帐户出现两次,一次出现在Master记录中,再次出现在下级记录中,后者将Master记录作为重复记录返回。
WITH Dup as (
SELECT 1 as track
,ExternalID DomEx
,ExternalID
,GUID DomGUID
,ModDate
from crm.Accounts
WHERE ExternalID is not null
UNION ALL
SELECT track +1
,OI.DomEx
,OG.ExternalID
,OG.GUID
,Og.ModDate
from crm.Accounts OG
INNER JOIN Dup OI on OI.ExternalID = OG.ExternalID
)
,
cte_dp as(
SELECT *,
ROW_NUMBER() OVER (PARTITION BY ExternalID Order by track, ModDate desc) rn
FROM Dup
)
SELECT * FROM cte_dp
这很遗憾地达到递归限制100,并且如果转义限制则无限期地运行。
是否可以在此更正逻辑以呈现所需的结果,或者是否有更优雅的解决方案。
+--------------+---------------------+--------------------+--+
| MasterGUID | SharedExternalID | SubordinateGUID | |
+--------------+---------------------+--------------------+--+
| (MasterGUID) | (SharedExternalID) | (SubordinateGUID) | |
| (MasterGUID) | (Shared ExternalID) | (SubordinateGUID) | |
+--------------+---------------------+--------------------+--+
我理想的结果是,MasterGUID是两个重复之间最近修改日期的GUID。
答案 0 :(得分:0)
MERGE Accounts a1
USING Accounts a2
ON a1.ExternalID = a2.ExternalID
WHEN MATCHED THEN
UPDATE
SET a1.ModifiedDate = a2.ModifiedDate,
a1.guid = a2.guid;
SELECT * FROM Accounts a1;
答案 1 :(得分:0)
a1.ExternalID = a2.ExternalID
是对称的,因此如果切换顺序,关系将具有相同的逻辑结果。因此,如果您找到这样的一对(例如,self),那么它将在结果中出现两次。我们需要在附加条件下打破对称性:
a1.ExternalID = a2.ExternalID and a1.GUID < a2.GUID
这将阻止加入自我。如果需要,可以使用union
,但现在我假设不需要。如果还存在ExternalID
的另一个匹配项,则如果左侧的GUID
比右侧严格小environment
,则匹配将生成true,因此反转将不为真且重复项将消失。< / p>
答案 2 :(得分:0)
如果您发布样本数据,这将更容易,但这是您的意思吗?
`const mongoose = require('mongoose');
const commentSchema = mongoose.Schema({
author: {type: String},
message: {type: String},
});
module.exports = mongoose.model('Comments', commentSchema);`