如何在新列中获取前三行和后三行的总和

时间:2019-01-15 10:51:18

标签: sql sql-server ssms sql-server-2016

你好,我有一个sql server内部连接

SELECT a.field_name, 
       b.ticker     AS Ticker_Name, 
       Year(c.date) AS YEAR, 
       c.stock_id, 
       c.field_id, 
       Sum(c.value) AS Value 
FROM   field_table a 
       INNER JOIN stock_transaction c 
               ON a.id = c.field_id 
       INNER JOIN stocks b 
               ON b.id = c.stock_id 
WHERE  b.id = 230 
       AND c.field_id = 29 
GROUP  BY Year(c.date), 
          b.ticker, 
          c.stock_id, 
          c.field_id, 
          a.field_name; 

我还附上了我的输出。

enter image description here

我的产出是每年的销售额总和。现在我的任务是我必须在新列中显示三行的值之和。例如:2008年,2009年,2010年,然后又是2011年,2012年,2013年的总和。然后是2014年,2015年,2016年

我的愿望输出是

enter image description here

任何人都可以建议我如何实现此功能。

2 个答案:

答案 0 :(得分:1)

您只想要lag()吗?

SELECT f.field_name, s.ticker AS Ticker_Name, 
       Year(st.date) AS YEAR, st.stock_id, st.field_id, 
       Sum(st.value) AS Value,
       LAG(Sum(st.value, 1)) OVER (PARTITION BY f.field_name, s.ticker, st.stock_id, st.field_id ORDER BY Year(st.date)) as year_1,
       LAG(Sum(st.value, 2)) OVER (PARTITION BY f.field_name, s.ticker, st.stock_id, st.field_id ORDER BY Year(st.date)) as year_2,
       LAG(Sum(st.value, 3)) OVER (PARTITION BY f.field_name, s.ticker, st.stock_id, st.field_id ORDER BY Year(st.date)) as year_3
FROM field_table f INNER JOIN
     stock_transaction st
     ON f.id = st.field_id INNER JOIN
     stocks s 
     ON s.id = st.stock_id 
WHERE s.id = 230 AND st.field_id = 29 
GROUP BY Year(st.date), s.ticker, st.stock_id, st.field_id, f.field_name; 

请注意,我还用表的缩写替换了表别名。您应该使用有意义的表别名(例如缩写),而不是任意字母。

答案 1 :(得分:0)

此答案只是一个基本示例,该示例演示了如何将每三行的值求和作为结果集中的新列。您可以更改此设置以适合您的需求。示例使用ROW_NUMBER()和整数除法来计算每个组号。

输入:

Year    Value   
2008    100.00  
2009    200.00  
2010    300.00  
2011    400.00  
2012    500.00  
2013    600.00  
2014    700.00  
2015    800.00  
2016    900.00  
2017    1000.00 
2018    1100.00 

声明:

-- Table
CREATE TABLE #Items (
    [Year] int,
    [Value] numeric(20, 2)
)
INSERT INTO #Items 
    ([Year], [Value])
VALUES
    (2008, 100),
    (2009, 200),
    (2010, 300),
    (2011, 400),
    (2012, 500),
    (2013, 600),
    (2014, 700),
    (2015, 800),
    (2016, 900),
    (2017, 1000),
    (2018, 1100)

-- Statement
;WITH cte AS (
    -- Generate group numbers. Each group is every tree years.
    SELECT 
        [Year], 
        [Value], 
        (ROW_NUMBER() OVER (ORDER BY [Year]) - 1) / 3 AS GroupNumber,
        ROW_NUMBER() OVER (ORDER BY [Year]) AS RowNumber
    FROM #Items
), sums AS (
    -- Get total sums for each group
    SELECT 
        SUM([Value]) AS [SumValue], 
        GroupNumber, 
        ROW_NUMBER() OVER (ORDER BY GroupNumber) AS RowNumber
    FROM cte
    GROUP BY [GroupNumber]
)
-- Final SELECT 
SELECT cte.[Year], cte.[Value], sums.[SumValue]
FROM cte
LEFT JOIN sums ON (cte.RowNumber = sums.RowNumber)

输出:

Year    Value   SumValue
2008    100.00  600.00
2009    200.00  1500.00
2010    300.00  2400.00
2011    400.00  2100.00
2012    500.00  NULL
2013    600.00  NULL
2014    700.00  NULL
2015    800.00  NULL
2016    900.00  NULL
2017    1000.00 NULL
2018    1100.00 NULL