SQL - 根据前两列计算第三列
SQL - Calculating third column from previous two
我刚开始SQL,在用这门语言思考方面有一些困难。
我现在有一个任务,我需要在 table 中使用之前列中的值创建一个新列。此计算基于几个条件。这甚至可以在 SQL 中轻松完成吗?
假设我有一个名为 dbo.country_sales 的 table,其中
Select *
From dbo.country
生成
CountryName, Year, Sales
—————————
Argentina, 2015, 10
Argentina, 2017, 22
Florida, 2015, 10
Florida, 2017, 8
Germany, 2015, null
Germany, 2017, null
我需要创建第四列,其中包含 2015 年至 2017 年的销售发展情况(2017 年的销售额 - 2015 年的销售额),因此 table 看起来像:
CountryName, Year, Sales, Development
—————————
Argentina, 2015, 10, 12
Argentina, 2017, 22, 12
Florida, 2015, 10, -2
Florida, 2017, 8, -2
Germany, 2015, null, null
Germany, 2017, null, null
我知道如何在 select 语句中创建它,但它只计算 1 个值。试图搜索几个小时,但没有找到任何简单的东西。
感谢您的帮助。
局域网
一个简单的方法使用 window 函数和条件聚合:
select c.*,
sum(case when year = 2017 then sales
when year = 2015 then - sales
end) over (partition by country) as diff_2017_2015
from dbo.country c
where year in (2015, 2017);
您可以使用 CTE 预先计算值。例如:
with a as (
select countryname, year, sales from t where year = 2015
),
b as (
select countryname, year, sales from t where year = 2017
),
c as (
select a.countryname, b.sales - a.sales as development
from a
join b on a.countryname = b.countryname
)
select a.*, c.development
from a
join c on c.countryname = a.countryname
union
select b.*, c.development
from b
join c on c.countryname = b.countryname
order by countryname, year
对于一个稍微更奇特的解决方案,可以为您在未来的使用中提供更大的灵活性,您可以创建一个辅助函数。
CREATE FUNCTION dbo.udf_SalesDiff(
@CountryName VARCHAR(50)
,@LookbackYear INT
,@CurrentSales MONEY
)
RETURNS MONEY
BEGIN
DECLARE @Diff MONEY
SELECT @Diff = @CurrentSales - [Sales]
FROM dbo.CountrySales
WHERE [CountryName] = @CountryName AND [Year] = @LookbackYear
RETURN @Diff
END
在哪里可以像这样使用它:
SELECT
[CountryName]
,[Year]
,dbo.udf_SalesDiff([CountryName],2015,[Sales]) AS Development
FROM dbo.CountrySales
WHERE [Year]=2017
并将产生:
CountryName | Year | Development
--------------------------------
Argentina | 2017 | 12
Florida | 2017 | -2
Germany | 2017 | NULL
我刚开始SQL,在用这门语言思考方面有一些困难。
我现在有一个任务,我需要在 table 中使用之前列中的值创建一个新列。此计算基于几个条件。这甚至可以在 SQL 中轻松完成吗?
假设我有一个名为 dbo.country_sales 的 table,其中
Select *
From dbo.country
生成
CountryName, Year, Sales
—————————
Argentina, 2015, 10
Argentina, 2017, 22
Florida, 2015, 10
Florida, 2017, 8
Germany, 2015, null
Germany, 2017, null
我需要创建第四列,其中包含 2015 年至 2017 年的销售发展情况(2017 年的销售额 - 2015 年的销售额),因此 table 看起来像:
CountryName, Year, Sales, Development
—————————
Argentina, 2015, 10, 12
Argentina, 2017, 22, 12
Florida, 2015, 10, -2
Florida, 2017, 8, -2
Germany, 2015, null, null
Germany, 2017, null, null
我知道如何在 select 语句中创建它,但它只计算 1 个值。试图搜索几个小时,但没有找到任何简单的东西。
感谢您的帮助。 局域网
一个简单的方法使用 window 函数和条件聚合:
select c.*,
sum(case when year = 2017 then sales
when year = 2015 then - sales
end) over (partition by country) as diff_2017_2015
from dbo.country c
where year in (2015, 2017);
您可以使用 CTE 预先计算值。例如:
with a as (
select countryname, year, sales from t where year = 2015
),
b as (
select countryname, year, sales from t where year = 2017
),
c as (
select a.countryname, b.sales - a.sales as development
from a
join b on a.countryname = b.countryname
)
select a.*, c.development
from a
join c on c.countryname = a.countryname
union
select b.*, c.development
from b
join c on c.countryname = b.countryname
order by countryname, year
对于一个稍微更奇特的解决方案,可以为您在未来的使用中提供更大的灵活性,您可以创建一个辅助函数。
CREATE FUNCTION dbo.udf_SalesDiff(
@CountryName VARCHAR(50)
,@LookbackYear INT
,@CurrentSales MONEY
)
RETURNS MONEY
BEGIN
DECLARE @Diff MONEY
SELECT @Diff = @CurrentSales - [Sales]
FROM dbo.CountrySales
WHERE [CountryName] = @CountryName AND [Year] = @LookbackYear
RETURN @Diff
END
在哪里可以像这样使用它:
SELECT
[CountryName]
,[Year]
,dbo.udf_SalesDiff([CountryName],2015,[Sales]) AS Development
FROM dbo.CountrySales
WHERE [Year]=2017
并将产生:
CountryName | Year | Development
--------------------------------
Argentina | 2017 | 12
Florida | 2017 | -2
Germany | 2017 | NULL