检测今天和昨天的帐户/负载之间差异的查询
Posted
技术标签:
【中文标题】检测今天和昨天的帐户/负载之间差异的查询【英文标题】:Query that detects difference between accounts/loads from TODAY and YESTERDAY 【发布时间】:2019-10-22 19:16:51 【问题描述】:目标:检测昨天的表负载和今天的负载之间的任何差异。每次加载都会加载与银行帐户关联的数据值。所以我需要一个查询来返回每个有差异的个人帐户,其值在列名中。
我需要来自两个不同表的多个列的数据。 AEI_GFXAccounts 和 AEI_GFXAccountSTP。每次加载表时,它都有一个递增 1 的“run_ID”。所以需要对比MAX(run_id)
和MAX(run_id) -1
。
我尝试了以下查询。这个查询所做的就是返回我需要的所有列。我现在需要实现运行这些查询WHERE runID = MAX(runID)
的逻辑。然后在run_ID = Max(runID) -1
处再次运行它。比较这两个表,显示可以在SELECT AccountBranch WHERE MAX(Run_ID) -1 AS WAS
等列下显示的差异。等,以及每个列的另一个自定义命名列为“IS NOW
”等。
SELECT AEI_GFXAccounts.AccountNumber,
AccountBranch,
AccountName,
AccountType,
CostCenter,
TransactionLimit,
ClientName,
DailyCumulativeLimit
FROM AEI_GFXAccounts
JOIN AEI_GFXAccountSTP
ON (AEI_GFXAccounts.feed_id = AEI_GFXAccountSTP.feed_id
and AEI_GFXAccounts.run_id = AEI_GFXAccountSTP.run_id)
【问题讨论】:
如果您有一个新帐户怎么办?它与先前加载中存在的不同,但您当前的查询将排除它。反过来呢 - 如果一个帐户没有出现在今天的负载中但昨天出现了 - 会发生什么? 如果有新账户,我们不在乎,因为没有变化,否定它,不要让它成为查询的一部分。不会有新账户。假设每个帐户都是相同的。假设每个帐户都将一直存在,如果它关闭,它就会保持静止。 【参考方案1】:我使用类似的东西来检测日志系统的变化:
WITH data AS (
SELECT
a.run_id,
a.AccountNumber,
?.AccountBranch,
?.AccountName,
?.AccountType,
?.CostCenter,
?.TransactionLimit,
?.ClientName,
?.DailyCumulativeLimit
FROM
AEI_GFXAccounts a
INNER JOIN AEI_GFXAccountSTP b
ON
a.feed_id = b.feed_id and
a.run_id = b.run_id
),
yest AS (
SELECT * FROM data WHERE run_id = (SELECT MAX(run_id)-1 FROM AEI_GFXAccounts)
),
toda AS (
SELECT * FROM data WHERE run_id = (SELECT MAX(run_id) FROM AEI_GFXAccounts)
)
SELECT
CASE WHEN COALESCE(yest.AccountBranch, 'x') <> COALESCE(toda.AccountBranch, 'x') THEN yest.AccountBranch END as yest_AccountBranch,
CASE WHEN COALESCE(yest.AccountBranch, 'x') <> COALESCE(toda.AccountBranch, 'x') THEN toda.AccountBranch END as toda_AccountBranch,
CASE WHEN COALESCE(yest.AccountName, 'x') <> COALESCE(toda.AccountName, 'x') THEN yest.AccountName END as yest_AccountName,
CASE WHEN COALESCE(yest.AccountName, 'x') <> COALESCE(toda.AccountName, 'x') THEN toda.AccountName END as toda_AccountName,
...
FROM
toda INNER JOIN yest ON toda.accountNumber = yestaccountNumber
注意事项:
您没有说明您的某些列来自哪个表。我已经为它们添加了前缀?.
- 分别用 a.
或 as.
替换它们(完全限定所有列别名的好习惯)
当您在底部选择(...上方)中重复模式时,选择不会出现在列中的 COALESCE 数据。我正在使用 COALESCE 作为避免编写 CASE WHEN a is null and b is not null or b is null and a is not null or a != b
的快速方法,但如果帐户名(例如)昨天为 'x'
而今天为空,则比较失败,因为空变为“x”。如果您选择永远不会出现在列中的数据,那么检查就会成功,因为空值将被合并到实际数据中永远不会出现的东西,因此<>
比较会成功
如果您不在乎某列今天何时从昨天的值变为 null,或者昨天为 null 但今天是一个值,您可以放弃合并,直接执行 toda.X <> yest.X
今天的新帐户要到明天才会显示。如果您希望他们出现,请执行toda LEFT JOIN yest ...
。当然,它们的所有属性都会显示为新属性;)
无论是否进行了任何更改,此查询都会返回所有帐户。如果您只想要一个有更改的帐户列表,则需要一个与您的案例 whens 类似的 where 子句:
WHERE
COALESCE(toda.AccountBranch, 'x') <> COALESCE(yest.AccountBranch, 'x') OR
COALESCE(toda.AccountName, 'x') <> COALESCE(yest.AccountName, 'x') OR
...
【讨论】:
就在 a.feed_id = b.feed_id 之后,第一个“)”之后,在 SSMS 中给我一个错误。说““)附近的语法不正确。” 哈,是的-我有点忘了 AS 是一个 SQL 关键字,它可能会合法地出现在表名之后,对此感到抱歉【参考方案2】:您有日期字段吗?如果是这样,您可以使用按您的帐户分区的 Row_Number。排除最大为 1 行“新帐户”的所有帐户,然后将每个帐户的负载的 Max(rownumber) 减去 Max(rownumber)-1 的负载。仅返回此返回负载大于 0 的帐户。您可以也使用 lag 函数来获取以前的帐户负载,而不是 Max(rownumber)-1
【讨论】:
以上是关于检测今天和昨天的帐户/负载之间差异的查询的主要内容,如果未能解决你的问题,请参考以下文章