SQL 通过条件行减去相同的列值并在 table 上插入新结果
SQL subtract same column values by conditional rows and insert new results on a table
我在 Snowflake 中有此代码以获得以下 table:
CREATE OR REPLACE TABLE LIVE_ANALYTICS.REPORTING."GL_REPORT"
AS
SELECT
SUM("TABLE_GL_ENTRY"."Amount" AS "AMOUNT",
MONTH("TABLE_GL_ENTRY"."Posting Date") AS "MONTH",
YEAR("TABLE_GL_ENTRY"."Posting Date") AS "YEAR",
"TABLE_GL_ENTRY"."Global Dimension 1 Code" AS "ID_STORE",
CASE
WHEN "YEAR" = YEAR(CURRENT_DATE()) THEN 'AMOUNT_CURRENT_YEAR'
ELSE 'AMOUNT_LAST_YEAR'
END AS "METRIC"
FROM
LIVE_ANALYTICS.NAVISION."G_L Entry" AS "TABLE_GL_ENTRY"
WHERE
(("MONTH" = MONTH(CURRENT_DATE()) OR "MONTH" = MONTH(ADD_MONTHS(CURRENT_DATE, 1)))
AND
("YEAR" = YEAR(CURRENT_DATE()) OR "YEAR" = YEAR(ADD_MONTHS(CURRENT_DATE, -12))))
AND
(("ID_STORE" LIKE '1')
OR
("ID_STORE" LIKE '2')
OR
("ID_STORE" LIKE '3'))
GROUP BY
MONTH",
"YEAR",
"ID_STORE",
;
从这个table我需要用“MONTH”和“ID_STORE”减去“AMOUNT”仅当“YEAR”= 2021。
AMOUNT_CURRENT_YEAR - AMOUNT_LAST_YEAR
最后,我想将这些新结果与其他现有记录一起插入到现有 table 中。
我该怎么做?有什么建议吗?
提前致谢
亲切的问候。
编辑:这是我前几天搜索的解决方案,谢谢大家!
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=9909600b9ac804ba67b7086c40e0c844
create table last_amount as
select sum(amount) as 'amount_last', month, year, id, metric
from data where metric like 'last'
group by month, year, id, metric
order by id, month, year;
create table current_amount as
select sum(amount) as 'amount_current', month, year, id, metric
from data where metric like 'current'
group by month, year, id, metric
order by id, month, year
create table subtract as
select
c.amount_current - l.amount_last as amount, c.month, c.year, c.id
from
last_amount l
join
current_amount c
on
l.id = c.id
and
l.month = c.month;
alter table subtract add metric varchar(255) default 'subtract';
insert into data
select * from subtract;
drop table last_amount;
drop table current_amount;
select * from data order by id, month, year;
这可能对您有所帮助,此代码可能不包含所有值,但它会让您了解逻辑。
以link为例:
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=7ad1e26d11b1c835fc77e9c4578bebf5
- 第一个:Select所有数据
- 其二:引入
lead ()
函数将最新的第1行向后移动
- 第三:根据你的逻辑减法
- 第四:使用
UNION
合并原始结果和新结果
with all_data as (
select * from data
),
last_year_current_year as (
select
*,
lead(amount) over(partition by id, month, year) as one_less
from all_data
)
,
subtraction as (
select
*,
one_less - amount as new_amount
from last_year_current_year
),
combining_data as (
select new_amount, month, year, id from subtraction
union
select amount, month, year, id from subtraction
)
select * from combining_data
您可以使用条件聚合和 insert
:
insert into LIVE_ANALYTICS.NAVISION."G_L Entry" (amount, month, year, id_store, metric)
select sum(case when metric = 'AMOUNT_CURRENT_YEAR' then amount
when metric = 'AMOUNT_LAST_YEAR' then - amount
end),
month, year, id_store, 'SUBTRACT_LAST_YEAR'
from LIVE_ANALYTICS.NAVISION."G_L Entry" gl
where year = 2021
group by month, year, id_store;
-- 这是在 SQL 服务器中,但我希望 MySql 中的逻辑也是一样的
创建 table #temp1
(
金额,
月数整数,
YearNum 整数,
ID_Store 整数,
公制 varchar(100)
);
插入#temp1 值(10,8,2020,1,'AMOUNT LAST YEAR')
插入#temp1 值(20,8,2021,1,'AMOUNT CURRENT YEAR')
插入#temp1 值(30,8,2020,2,'AMOUNT LAST YEAR')
插入#temp1 值(40,8,2021,2,'AMOUNT CURRENT YEAR')
插入#temp1 值(50,8,2020,3,'AMOUNT LAST YEAR')
插入#temp1 值(60,8,2021,3,'AMOUNT CURRENT YEAR')
插入#temp1 值(70,9,2020,1,'AMOUNT__YEAR')
插入#temp1 值(0,9,2021,1,'AMOUNT CURRENT YEAR')
插入#temp1 值(90,9,2020,2,'AMOUNT__YEAR')
插入#temp1 值(0,9,2021,2,'AMOUNT CURRENT YEAR')
插入#temp1 值(110,9,2020,3,'AMOUNT__YEAR')
插入#temp1 值(0,9,2021,3,'AMOUNT CURRENT YEAR')
-- 实际代码从这里开始
Select
(t1.Amount-t3.Amount) 作为金额
,t1.MonthNum
,t1.YearNum
,t1.ID_Store
,'Modified Metric' 作为公制
进入#temp2
来自 #temp1 t1
加入(Select t2.Amount,t2.MonthNum,t2.ID_Store 来自#temp1 t2,其中 t2.YearNum=2020)t3 ON t1.MonthNum=t3.MonthNum和 t1.ID_Store=t3.ID_Store
其中 t1.YearNum=2021
插入#temp1
select * 来自#temp2
-- 结束实际代码从这里开始
Select * 来自#temp1;
下降 table #temp1;
下降 table #temp2;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=9909600b9ac804ba67b7086c40e0c844
create table data ( amount int, month int, year int, id int, metric varchar(255) );
insert into data values (10, 8, 2020, 1, 'last');
insert into data values (20, 8, 2021, 1, 'current');
insert into data values (30, 8, 2020, 2, 'last');
insert into data values (60, 8, 2021, 3, 'current');
insert into data values (70, 9, 2020, 1, 'last');
insert into data values (0, 9, 2021, 1, 'current');
insert into data values (90, 9, 2020, 2, 'last');
insert into data values (40, 8, 2021, 2, 'current');
insert into data values (50, 8, 2020, 3, 'last');
insert into data values (0, 9, 2021, 2, 'current');
insert into data values (110, 9, 2020, 3, 'last');
insert into data values (0, 9, 2021, 3, 'current');
select * from data order by id, month, year
create table last_amount as
select sum(amount) as 'amount_last', month, year, id, metric
from data where metric like 'last'
group by month, year, id, metric
order by id, month, year;
create table current_amount as
select sum(amount) as 'amount_current', month, year, id, metric
from data where metric like 'current'
group by month, year, id, metric
order by id, month, year
create table subtract as
select
c.amount_current - l.amount_last as amount, c.month, c.year, c.id
from
last_amount l
join
current_amount c
on
l.id = c.id
and
l.month = c.month;
alter table subtract add metric varchar(255) default 'subtract';
insert into data
select * from subtract;
drop table last_amount;
drop table current_amount;
select * from data order by id, month, year;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=6a50ae3dce1eda02250d79fbb6f95ca7
create table data ( amount int, month int, year int, id int, metric varchar(255) );
insert into data values (10, 8, 2020, 1, 'last');
insert into data values (20, 8, 2021, 1, 'current');
insert into data values (30, 8, 2020, 2, 'last');
insert into data values (60, 8, 2021, 3, 'current');
insert into data values (70, 9, 2020, 1, 'last');
insert into data values (0, 9, 2021, 1, 'current');
insert into data values (90, 9, 2020, 2, 'last');
insert into data values (40, 8, 2021, 2, 'current');
insert into data values (50, 8, 2020, 3, 'last');
insert into data values (0, 9, 2021, 2, 'current');
insert into data values (110, 9, 2020, 3, 'last');
insert into data values (0, 9, 2021, 3, 'current');
select * from data order by id, month, year
select * from data
union all
select
c.amount - l.amount as amount, c.month, c.year, c.id, 'subtract' as metric
from
data c
right join
data l
on
l.id = c.id
and
l.month = c.month
where c.year = 2021
and c.amount - l.amount != 0
order by id, month, year;
更好的选择:
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=4273a6e920b54e118868ca44a5927cce
create table data ( amount int, month int, year int, id int, metric
varchar(255) );
insert into data values (10, 8, 2020, 1, 'last');
insert into data values (20, 8, 2021, 1, 'current');
insert into data values (30, 8, 2020, 2, 'last');
insert into data values (60, 8, 2021, 3, 'current');
insert into data values (70, 9, 2020, 1, 'last');
insert into data values (0, 9, 2021, 1, 'current');
insert into data values (90, 9, 2020, 2, 'last');
insert into data values (40, 8, 2021, 2, 'current');
insert into data values (50, 8, 2020, 3, 'last');
insert into data values (0, 9, 2021, 2, 'current');
insert into data values (110, 9, 2020, 3, 'last');
insert into data values (0, 9, 2021, 3, 'current');
select * from data order by id, month, year
select * from data
union all
select
c.amount - l.amount as amount, c.month, c.year, c.id, 'subtract' as metric
from
(select * from data where year = 2021) c
left join
(select * from data where year = 2020) l
on
l.id = c.id
and
l.month = c.month
order by id, month, year, metric;
我在 Snowflake 中有此代码以获得以下 table:
CREATE OR REPLACE TABLE LIVE_ANALYTICS.REPORTING."GL_REPORT"
AS
SELECT
SUM("TABLE_GL_ENTRY"."Amount" AS "AMOUNT",
MONTH("TABLE_GL_ENTRY"."Posting Date") AS "MONTH",
YEAR("TABLE_GL_ENTRY"."Posting Date") AS "YEAR",
"TABLE_GL_ENTRY"."Global Dimension 1 Code" AS "ID_STORE",
CASE
WHEN "YEAR" = YEAR(CURRENT_DATE()) THEN 'AMOUNT_CURRENT_YEAR'
ELSE 'AMOUNT_LAST_YEAR'
END AS "METRIC"
FROM
LIVE_ANALYTICS.NAVISION."G_L Entry" AS "TABLE_GL_ENTRY"
WHERE
(("MONTH" = MONTH(CURRENT_DATE()) OR "MONTH" = MONTH(ADD_MONTHS(CURRENT_DATE, 1)))
AND
("YEAR" = YEAR(CURRENT_DATE()) OR "YEAR" = YEAR(ADD_MONTHS(CURRENT_DATE, -12))))
AND
(("ID_STORE" LIKE '1')
OR
("ID_STORE" LIKE '2')
OR
("ID_STORE" LIKE '3'))
GROUP BY
MONTH",
"YEAR",
"ID_STORE",
;
从这个table我需要用“MONTH”和“ID_STORE”减去“AMOUNT”仅当“YEAR”= 2021。
AMOUNT_CURRENT_YEAR - AMOUNT_LAST_YEAR
最后,我想将这些新结果与其他现有记录一起插入到现有 table 中。
我该怎么做?有什么建议吗?
提前致谢
亲切的问候。
编辑:这是我前几天搜索的解决方案,谢谢大家!
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=9909600b9ac804ba67b7086c40e0c844
create table last_amount as
select sum(amount) as 'amount_last', month, year, id, metric
from data where metric like 'last'
group by month, year, id, metric
order by id, month, year;
create table current_amount as
select sum(amount) as 'amount_current', month, year, id, metric
from data where metric like 'current'
group by month, year, id, metric
order by id, month, year
create table subtract as
select
c.amount_current - l.amount_last as amount, c.month, c.year, c.id
from
last_amount l
join
current_amount c
on
l.id = c.id
and
l.month = c.month;
alter table subtract add metric varchar(255) default 'subtract';
insert into data
select * from subtract;
drop table last_amount;
drop table current_amount;
select * from data order by id, month, year;
这可能对您有所帮助,此代码可能不包含所有值,但它会让您了解逻辑。
以link为例:
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=7ad1e26d11b1c835fc77e9c4578bebf5
- 第一个:Select所有数据
- 其二:引入
lead ()
函数将最新的第1行向后移动 - 第三:根据你的逻辑减法
- 第四:使用
UNION
合并原始结果和新结果
with all_data as (
select * from data
),
last_year_current_year as (
select
*,
lead(amount) over(partition by id, month, year) as one_less
from all_data
)
,
subtraction as (
select
*,
one_less - amount as new_amount
from last_year_current_year
),
combining_data as (
select new_amount, month, year, id from subtraction
union
select amount, month, year, id from subtraction
)
select * from combining_data
您可以使用条件聚合和 insert
:
insert into LIVE_ANALYTICS.NAVISION."G_L Entry" (amount, month, year, id_store, metric)
select sum(case when metric = 'AMOUNT_CURRENT_YEAR' then amount
when metric = 'AMOUNT_LAST_YEAR' then - amount
end),
month, year, id_store, 'SUBTRACT_LAST_YEAR'
from LIVE_ANALYTICS.NAVISION."G_L Entry" gl
where year = 2021
group by month, year, id_store;
-- 这是在 SQL 服务器中,但我希望 MySql 中的逻辑也是一样的 创建 table #temp1 ( 金额, 月数整数, YearNum 整数, ID_Store 整数, 公制 varchar(100) );
插入#temp1 值(10,8,2020,1,'AMOUNT LAST YEAR') 插入#temp1 值(20,8,2021,1,'AMOUNT CURRENT YEAR') 插入#temp1 值(30,8,2020,2,'AMOUNT LAST YEAR') 插入#temp1 值(40,8,2021,2,'AMOUNT CURRENT YEAR') 插入#temp1 值(50,8,2020,3,'AMOUNT LAST YEAR') 插入#temp1 值(60,8,2021,3,'AMOUNT CURRENT YEAR') 插入#temp1 值(70,9,2020,1,'AMOUNT__YEAR') 插入#temp1 值(0,9,2021,1,'AMOUNT CURRENT YEAR') 插入#temp1 值(90,9,2020,2,'AMOUNT__YEAR') 插入#temp1 值(0,9,2021,2,'AMOUNT CURRENT YEAR') 插入#temp1 值(110,9,2020,3,'AMOUNT__YEAR') 插入#temp1 值(0,9,2021,3,'AMOUNT CURRENT YEAR')
-- 实际代码从这里开始 Select (t1.Amount-t3.Amount) 作为金额 ,t1.MonthNum ,t1.YearNum ,t1.ID_Store ,'Modified Metric' 作为公制 进入#temp2 来自 #temp1 t1 加入(Select t2.Amount,t2.MonthNum,t2.ID_Store 来自#temp1 t2,其中 t2.YearNum=2020)t3 ON t1.MonthNum=t3.MonthNum和 t1.ID_Store=t3.ID_Store 其中 t1.YearNum=2021
插入#temp1 select * 来自#temp2
-- 结束实际代码从这里开始
Select * 来自#temp1;
下降 table #temp1; 下降 table #temp2;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=9909600b9ac804ba67b7086c40e0c844
create table data ( amount int, month int, year int, id int, metric varchar(255) );
insert into data values (10, 8, 2020, 1, 'last');
insert into data values (20, 8, 2021, 1, 'current');
insert into data values (30, 8, 2020, 2, 'last');
insert into data values (60, 8, 2021, 3, 'current');
insert into data values (70, 9, 2020, 1, 'last');
insert into data values (0, 9, 2021, 1, 'current');
insert into data values (90, 9, 2020, 2, 'last');
insert into data values (40, 8, 2021, 2, 'current');
insert into data values (50, 8, 2020, 3, 'last');
insert into data values (0, 9, 2021, 2, 'current');
insert into data values (110, 9, 2020, 3, 'last');
insert into data values (0, 9, 2021, 3, 'current');
select * from data order by id, month, year
create table last_amount as
select sum(amount) as 'amount_last', month, year, id, metric
from data where metric like 'last'
group by month, year, id, metric
order by id, month, year;
create table current_amount as
select sum(amount) as 'amount_current', month, year, id, metric
from data where metric like 'current'
group by month, year, id, metric
order by id, month, year
create table subtract as
select
c.amount_current - l.amount_last as amount, c.month, c.year, c.id
from
last_amount l
join
current_amount c
on
l.id = c.id
and
l.month = c.month;
alter table subtract add metric varchar(255) default 'subtract';
insert into data
select * from subtract;
drop table last_amount;
drop table current_amount;
select * from data order by id, month, year;
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=6a50ae3dce1eda02250d79fbb6f95ca7
create table data ( amount int, month int, year int, id int, metric varchar(255) );
insert into data values (10, 8, 2020, 1, 'last');
insert into data values (20, 8, 2021, 1, 'current');
insert into data values (30, 8, 2020, 2, 'last');
insert into data values (60, 8, 2021, 3, 'current');
insert into data values (70, 9, 2020, 1, 'last');
insert into data values (0, 9, 2021, 1, 'current');
insert into data values (90, 9, 2020, 2, 'last');
insert into data values (40, 8, 2021, 2, 'current');
insert into data values (50, 8, 2020, 3, 'last');
insert into data values (0, 9, 2021, 2, 'current');
insert into data values (110, 9, 2020, 3, 'last');
insert into data values (0, 9, 2021, 3, 'current');
select * from data order by id, month, year
select * from data
union all
select
c.amount - l.amount as amount, c.month, c.year, c.id, 'subtract' as metric
from
data c
right join
data l
on
l.id = c.id
and
l.month = c.month
where c.year = 2021
and c.amount - l.amount != 0
order by id, month, year;
更好的选择:
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=4273a6e920b54e118868ca44a5927cce
create table data ( amount int, month int, year int, id int, metric
varchar(255) );
insert into data values (10, 8, 2020, 1, 'last');
insert into data values (20, 8, 2021, 1, 'current');
insert into data values (30, 8, 2020, 2, 'last');
insert into data values (60, 8, 2021, 3, 'current');
insert into data values (70, 9, 2020, 1, 'last');
insert into data values (0, 9, 2021, 1, 'current');
insert into data values (90, 9, 2020, 2, 'last');
insert into data values (40, 8, 2021, 2, 'current');
insert into data values (50, 8, 2020, 3, 'last');
insert into data values (0, 9, 2021, 2, 'current');
insert into data values (110, 9, 2020, 3, 'last');
insert into data values (0, 9, 2021, 3, 'current');
select * from data order by id, month, year
select * from data
union all
select
c.amount - l.amount as amount, c.month, c.year, c.id, 'subtract' as metric
from
(select * from data where year = 2021) c
left join
(select * from data where year = 2020) l
on
l.id = c.id
and
l.month = c.month
order by id, month, year, metric;