SQL Server表计算

时间:2017-08-18 05:43:00

标签: sql sql-server

假设:

+-----------+---------------+-------------+-------+
|   Name    |   Item        | Year        | Value |
+-----------+---------------+-------------+-------+
| Company A | Sales         | 2017        |   100 |
| Company A | Sales         | 2016        |   100 |
| Company A | Sales         | 2015        |   400 |
| Company A | Profit        | 2017        |    50 |
| Company A | Profit        | 2016        |    50 |
| Company A | Profit        | 2015        |   200 |
| Company B | Sales         | 2017        |   200 |
| Company B | Sales         | 2016        |   100 |
| Company B | Profit        | 2017        |    20 |
| Company B | Profit        | 2016        |    20 |
+-----------+---------------+-------------+-------+

如何使用SQL将其转换为:

+----------+---------------+--------+-----------+
|   Name   |   Year        | Margins| 2 yr Ave  |
+----------+---------------+--------+-----------+
| CompanyA | 2015          |    50% |    NULL   |  
| CompanyA | 2016          |    50% |    50%    |  
| CompanyA | 2017          |    50% |    50%    |  
| CompanyB | 2016          |    20% |    NULL   |
| CompanyB | 2017          |    10% |    15%    |
+----------+---------------+--------+-----------+

+----------+---------------+--------+-----------+
|   Name   |   Year        | CompA  | CompB     |
+----------+---------------+--------+-----------+
| Margin   | 2015          |    50% |    NULL   |  
| Margin   | 2016          |    50% |    20%    |  
| Margin   | 2017          |    50% |    10%    |  
| 2Yr Ave  | 2015          |   NULL |    NULL   |
| 2Yr Ave  | 2016          |    50% |    NULL   |
| 2Yr Ave  | 2017          |    50% |    15%    |
+----------+---------------+--------+-----------+
  • 保证金:(特定年份的利润/销售额* 100)和
  • 2年大道:今年保证金+上一年度保证金/ 2,NULL如果没有上一年的数据。

2 个答案:

答案 0 :(得分:6)

我的方法是首先使用GROUP BY在您的桌子上汇总一次,以计算每年每家公司的利润率。然后,使用LAG()进行第二次传递,以计算最近两年的保证金平均值。

WITH cte AS (
    SELECT
        Name,
        Year,
        100*MAX(CASE WHEN Item = 'Profit' THEN Value END) /
            MAX(CASE WHEN Item = 'Sales' THEN Value END) AS Margins
    FROM yourTable
    GROUP BY
        Name,
        Year
)

SELECT
    Name,
    Year,
    Margins,
    (Margins + LAG(Margins) OVER (PARTITION BY Name ORDER BY Year)) / 2 AS [2 yr Avg]
FROM cte
ORDER BY
    Name,
    Year

对于第二个表输出,您只需从此查询中转动结果即可。将我给你的代码放入CTE,然后在边距列上转动。

<强>输出:

enter image description here

在这里演示:

Rextester

答案 1 :(得分:0)

在这一点上,你没有包括任何尝试,我只是发表一个想法,向你展示一种可能的方法。

SELECT T1.Name, T1.Year, Margins = 100 * T2.Value / T1.Value
FROM TBL1 T1
INNER JOIN TBL1 T2 ON T1.Name = T2.Name AND T1.Year = T2.Year AND T1.Item = 'Sales' AND T2.Item = 'Profit'
GROUP BY T1.Name, T1.Year

我正在做的是加入表格以便在同一行中获得所需的值,这样您就可以轻松地进行计算。

这样你就得到了没有平均值的第一个结果表。然后我会使用这个结果作为第二个查询的源来计算平均值,同时也将表连接到自身。

你的第二个结果表与第一个结果表是相同的但是转置了。如果您搜索它,您会找到大量信息,例如here