首页 > 解决方案 > 根据表中值的存在采取不同的行动

问题描述

我有一个表,我在其中添加了其他表中特定列的值的更改:

更新日志表:

表名 列过滤器 过滤器名称 筛选值 不同之处 日期
水果 水果名称 苹果 4 0 2021 年 1 月 13 日
水果 水果名称 5 0 2021 年 1 月 13 日

当我根据表的最后更新日期插入新记录时,我在确定插入条件时遇到了问题。

例如,昨天我的库存Apples等于4,今天等于5。因此,在我的 UpdatesLog 表中,我将插入Fruits-FruitName-Apple-5. 在列中Difference,我将计算昨天和今天的值之间的差异,即1. 这没关系,因为我已经将 Apple 作为 FilterName 列中的值。

但是,如果在我最后一次更新中Fruits table添加新FruitName - Peach的,我应该如何检查该值是否不存在并将其添加为默认值Difference value equal to 0

以下是 1 月 14 日的最后一次更新:

水果 水果库存 上次更新日期
苹果 5 2021 年 1 月 14 日
9 2021 年 1 月 14 日
10 2021 年 1 月 14 日

这是我期待的结果:

表名 列过滤器 过滤器名称 筛选值 差异 日期
水果 水果名称 苹果 4 0 2021 年 1 月 13 日
水果 水果名称 5 0 2021 年 1 月 13 日
水果 水果名称 苹果 5 1 2021 年 1 月 14 日
水果 水果名称 9 4 2021 年 1 月 14 日
水果 水果名称 10 0 2021 年 1 月 14 日

这是我的代码,以防我不检查水果名称是否存在:

INSERT INTO UpdatesLogTable(TableName, ColumnFilter, FilterName, FilterValue, [Difference], [Date])
SELECT [TableName]
    , [ColumnFilter]
    , [FilterName]
    , [FilterValue]
    , [Difference]
    , LUP as [Date]
FROM (
    SELECT tr.TableName
    , tr.ColumnFilter
    , tr.FilterName
    , tr.FilterValue
    , tr.[FilterValue] - ult.[FilterAbsValue] AS [Difference]
    , LUP
    FROM (SELECT
                'Fruits' as [TableName]
                , 'FruitName' as [ColumnFilter]
                ,  FruitName as [FilterName]
                , FruitsInventory AS [FilterValue]
                , MAX(LastUpdateDate as date) as LUP
            FROM Fruits  
            WHERE 1=1
            ) tr
    RIGHT JOIN UpdatesLogTable ult 
    ON tr.TableName = ult.TableName and tr.ColumnFilter = ult.ColumnFilter 
    WHERE hus.LastUpdateDate = (SELECT MAX(CAST(LastUpdateDate as date)) FROM UpdatesLogTable)
) a

我在考虑 LEFT 或 RIGHT 加入,但这只有在我知道水果品种是增加还是减少时才有效。

标签: sqlsql-servertsqlsql-insert

解决方案


您问题中的代码相当混乱。例如:

  • #HistoryUpdatesSuccess没有定义。
  • 您有一个格式错误的聚合子查询,使用FRUITS.
  • JOIN条件缺少过滤器值。

但是,我想我了解您想要做什么——插入新行,DIFF其中包含包含现有数据中最新数据的列。

这看起来像是LEFT JOIN历史表中最近的记录。剩下的只是COALESCE()

INSERT INTO UpdatesLogTable(TableName, ColumnFilter, FilterName, FilterValue, [Difference], [Date])
    SELECT f.TableName, f.ColumnFilter, f.FilterName, f.FilterValue,
           COALESCE(f.FilterValue - ult.FilterValue, 0), 
           LUP as [Date]
    FROM FRUITS F LEFT JOIN
         (SELECT ult.*,
                 ROW_NUMBER() OVER (PARTITION BY TableName, ColumnFilter ORDER BY LastUpdateDate) as seqnum
          FROM UpdatesLogTable ult 
         ) ult
         ON tr.TableName = ult.TableName AND
            tr.ColumnFilter = ult.ColumnFilter AND
            tr.FilterName = ult.FilterName
            seqnum = 1;

推荐阅读