简体   繁体   中英

How to subtract row 1 from row 2 and insert the result in row 3 in SQL Server?

I am looking for help to find a code that can subtract the returns of RANK_1 from RANK_5 and consequently insert the results in the row RANK_5M1 .

在此处输入图片说明

Here is the code for the table:

CREATE TABLE [dbo].[MOMENTUM_Money]
(
     [MNEMONIC] [varchar](50) NULL,
     [2006-12-30] [money] NULL,
     [2007-01-30] [money] NULL,
     [2007-02-28] [money] NULL
) ON [PRIMARY]
GO

INSERT INTO momentum_money (MNEMONIC, [2006-12-30],  [2007-01-30], [2007-02-28])
VALUES ('RANK_1', 131.8389, 141.1965, 147.9428),
       ('RANK_5', 36150.3798, 40087.5547, 38068.4299)

I saw I could use the lead and lag functions but I am completely lost.

You can use aggregation for this:

insert into MOMENTUM_Money
select 'Rank_5M1',
    sum([2006-12-30] * case when mnemonic = 'Rank_5' then 1 else - 1 end) [2006-12-30],
    sum([2007-01-30] * case when mnemonic = 'Rank_5' then 1 else - 1 end) [2007-01-30],
    sum([2006-02-28] * case when mnemonic = 'Rank_5' then 1 else - 1 end) [2007-02-28]
from MOMENTUM_Money
where mnemonic in ('Rank_1', 'Rank_5')

Demo

How it works:

The case statement produces 1 if mnemonic is Rank_5 otherwise -1.

What we want to do is mnemonic when rank_5 - mnemonic when rank_1 , which can be expressed as - mnemonic * (1 when rank_5) + mnemonic * (-1 when rank_1) . The 1 and -1 is produced by the case and summation is done by the sum() function.

Note that this may very well be a bad idea as it introduces redundancy into your data. A view (or user query) is usually a better place to perform this calculation. That said:

How this might work with LEAD or LAG depends on what other data might be in the table. To directly perform just the update as described (without concern about what other data is in the table, assuming at least mnemonic is unique), you could do something like

UPDATE momentum_returns
   SET [2006-12-30] = R5.[2006-12-30] - R1.[2006-12-30],
       [2007-01-30] = R5.[2007-01-30] - R1.[2007-01-30],
       [2007-02-28] = R5.[2007-02-28] - R1.[2007-02-28]
  FROM            momentum_returns AS R5
       inner join momentum_returns AS R1
               on R5.MNEMONIC = 'RANK_5'
              and R1.MNEMONIC = 'RANK_1'
 WHERE momentum_returns.MNEMONIC = 'RANK_5M1'
                    DECLARE @TABLENAME AS VARCHAR(max);
                    DECLARE @COLUMN1 AS VARCHAR(max);
                    DECLARE @COUNTER INT;
                    DECLARE @R1 as money, @R5 as money
                    DECLARE @SQL as VARCHAR(MAX)



                SET @TABLENAME = 'MOMENTUM_Results';
                SET @COUNTER = 2;

               WHILE @COUNTER<=4
               BEGIN

                 SELECT @COLUMN1 = C.Name
                FROM sys.Columns C
                WHERE OBJECT_NAME(C.object_id) = @TABLENAME 
               AND C.column_id = @COUNTER
                   ;


                    SET @SQL = 'DECLARE @R1 as money; DECLARE @R5 as money; 
                    SET @R1 = (SELECT [' + @COLUMN1 + '] FROM                     MOMENTUM_Results WHERE MNEMONIC = ''RANK_1''); 
                     SET @R5 = (SELECT [' + @COLUMN1 + '] FROM MOMENTUM_Results WHERE MNEMONIC = ''RANK_5'');
                     UPDATE MOMENTUM_Results SET [' + @COLUMN1 + '] = @R1 - @R5 WHERE MNEMONIC = ''RANK_5M1'''

                    EXECUTE (@SQL)




                   SET @COUNTER = @COUNTER + 1;

                   END
                     ;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM