【问题标题】:Computed column based on other computed column within insert procedure基于插入过程中其他计算列的计算列
【发布时间】:2015-06-02 10:34:02
【问题描述】:

我正在创建一个简单的数据库,其中包含允许我(使用 excel)分析我的冷水、温水、电等的消耗量以及这些数据的费用。

我将在 excel 中使用 useforms 将数据插入数据库,因此我创建了一个 SQL 过程。下面是插入冷水数据的示例。

我将两个重要参数传递给程序:@Price 和@Reading。 在 [冷水] 表中,我还有列:消耗和成本。

我想要做的是首先计算当月的消耗量(作为实际的@Reading - 以前的读数)。然后,计算出当前消耗后,我想使用该值并计算成本(当前消耗 * @Price)。

我已经设法使用子查询计算当前消耗和成本。但我很好奇是否(以及如何可能)我可以直接使用尚未插入的计算值(当前消耗)来计算一个插入中的另一个(成本)而不是使用子查询。

我想到的唯一想法是编写一个在此插入之后执行的触发器。 另外我不知道如何使用此过程将第一行插入表中,而不是手动插入第一行。

如果有任何提示,我将不胜感激。

@Date       AS DATE,
@Reading        AS DECIMAL (6,3),
@Price      AS DECIMAL (6,2),
@Unit   AS VARCHAR (5)

AS
    BEGIN
        SET NOCOUNT ON


-- Cold water
IF NOT EXISTS
        (
        SELECT Date
        FROM [Cold water]
        WHERE Date = @Date
        )
         BEGIN
            INSERT INTO dbo.[Cold water] 
            (
                Date,
                Year,
                Month,
                Day,
                Reading,
                Consumption,
                Unit,
                Price,
                Cost
            )
            VALUES
            (
                @Date,
                (SELECT YEAR(@Date)),
                (SELECT MONTH(@Date)),
                (SELECT DAY(@Date)),
                @Reading,
                (SELECT 
                    (@Reading - (SELECT Reading FROM [Cold water] WHERE ID = (SELECT MAX(ID) FROM [Cold water]))
                    )
                ),
                @Unit,
                @Price,
                (SELECT @Price* (SELECT (@Reading - (SELECT Reading FROM [Cold water] WHERE ID = (SELECT MAX(ID) FROM  [Cold water])
                                                   )
                                        )
                                )
                )
            )
        END 

【问题讨论】:

  • 这适用于哪个 RDBMS?请添加标签以指定您使用的是mysqlpostgresqlsql-serveroracle 还是db2 - 或完全其他的东西。
  • 我已添加 - SQL Server。

标签: sql sql-server stored-procedures calculated-columns


【解决方案1】:

你可以使用insert . . . select做你想做的事:

INSERT INTO dbo.[Cold water](Date, Year, Month, Day, Reading,
                             Consumption, Unit, Price, Cost)
    SELECT @Date, YEAR(@Date), MONTH(@Date), DAY(@Date), @Reading,
           c.Consumption, @Unit, @Price, @Price * c.Consumption
    FROM (SELECT (@Reading - Reading)  as Consumption
          FROM [Cold water]
          WHERE ID = (SELECT MAX(ID) FROM [Cold water])
         ) c;

一些cmets:

  • 您过度使用嵌套选择。这些不仅仅是应用函数所必需的。
  • 如果要存储日期,则不需要存储日期组件。这就是数据库包含year()month() 等函数的原因。
  • cost 的计算最好作为计算列来完成。

编辑:

您可以将计算列添加为:

alter table dbo.[Cold water] add year as (year(date));

或:

alter table dbo.[Cold water] add cost as (unit * price);

对于 Excel,这些将显示为真正的列。我建议对所有可以计算的列使用此逻辑。

【讨论】:

  • 谢谢,这个答案有效。我存储的日期组件只是为了查看它如何与 Excel Power Pivot 一起使用,因为它不允许像普通数据透视表那样按月、天等对日期进行分组,它需要为每个日期组件设置单独的列。您的意思是在创建表时将成本作为计算列吗?你能提供这个案例的外观吗?是否可以在创建表时使用参数 @Price 作为此计算的一部分?还是我想错了?
猜你喜欢
  • 2011-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多