我有一个系统,该系统接收对表中数据的更新。更新的所有列都允许使用null,这意味着如果收到null,则任何旧值都应保持不变。
该表还包含数字列(称为值)和非数字列(称为属性)。
应该将值简单地添加在一起...但是对于属性,应该选择最新的更新。
真正的问题是仅仅获取所有属性的最新更新,但是我之所以包含values列,只是因为它是现实生活中的一部分。
该解决方案今天可以运行,但不是很稳定。它只是简单地一个接一个地处理更新,并确保以与到达它们相同的顺序对其进行读取。
不幸的是,有时这会导致大量的循环,因为一天中很容易有成千上万个不同的“到达时间”。 这意味着每次收到更新时,即使只有一行也是如此...我创建了一个全新的结果表,可能只有一个更改。
我希望这可以作为单个SQL运行,而不是在服务器外部进行很多循环。
另一个问题是值列和属性列的数量很多。 (总计70-100。)
我创建了一个SQL提琴,以解决该问题...但是我目前的最佳想法是使用交叉应用(我使用MSSQL Server 2017,所以这是可能的。)
sqlfiddle.com /#!18 / 0a8a9 / 2
(小提琴显示了一个示例,并在此过程中解释了一些其他内容。)
即使只有3行需要检查“最新”的示例,代码也无法控制。 如果要实现这一点,那将是完全无法管理的,而且我也不是很确定优化程序会如何看待这40-50个连接/应用。
如何实现? 作为单个SQL(允许很多CTE等)。 无需为每个属性添加很多行?
如果由于某些错误的设计而最终导致此问题,请也告诉我。尤其是在设计上稍作改动就可以解决问题。
答案 0 :(得分:0)
尝试以下查询。请仔细检查语法。
;WITH cte_dates (ItemNumber, CorrectionTime_A1, CorrectionTime_A2, CorrectionTime_A3)
AS
(
SELECT ItemNumber,
MAX(CASE WHEN Attribute1 IS NULL THEN NULL ELSE CorrectionTime END) AS CorrectionTime_A1,
MAX(CASE WHEN Attribute2 IS NULL THEN NULL ELSE CorrectionTime END) AS CorrectionTime_A2,
MAX(CASE WHEN Attribute3 IS NULL THEN NULL ELSE CorrectionTime END) AS CorrectionTime_A3
FROM Updates
GROUP BY ItemNumber
)
SELECT u.ItemNumber,
MAX(CASE WHEN u.CorrectionTime=m.CorrectionTime_A1 THEN Attribute1 ELSE NULL END) AS Attribute1,
MAX(CASE WHEN u.CorrectionTime=m.CorrectionTime_A2 THEN Attribute2 ELSE NULL END) AS Attribute2,
MAX(CASE WHEN u.CorrectionTime=m.CorrectionTime_A3 THEN Attribute3 ELSE NULL END) AS Attribute3,
SUM(Value1) AS Value1,
SUM(Value2) AS Value2,
SUM(Value3) AS Value3
FROM cte_dates m
INNER JOIN Updates u
ON m.ItemNumber=u.ItemNumber
GROUP BY u.ItemNumber;