有人可以建议我,如何通过一些计算来创建PIVOT? 带有“真实数据”的简单PIVOT没问题,但是我不知道如何包括一些基本的计算,例如在某些列之间减去值...
请,如果您有能力,请尝试使用下面的表和数据示例...
-- Structure
-- ---------
-- Table of Products
CREATE TABLE ListProducts
(
ProductID INT IDENTITY(1,1) PRIMARY KEY,
Name NVARCHAR(25)
);
-- Table of Processes
CREATE TABLE ListProcesses
(
ProcessID INT IDENTITY(1,1) PRIMARY KEY,
Name NVARCHAR(25)
);
-- DataTable
CREATE TABLE Production
(
ProductionID INT IDENTITY(1,1) PRIMARY KEY,
ProductID INT FOREIGN KEY REFERENCES ListProducts(ProductID),
ProcessID INT FOREIGN KEY REFERENCES ListProcesses(ProcessID),
Amount INT
);
-- Data
-- ----
INSERT INTO ListProducts(Name) VALUES ('Product1'),('Product2'),('Product3');
INSERT INTO ListProcesses(Name) VALUES ('Process1'),('Process2'),('Process3');
INSERT INTO Production(ProductID,ProcessID,Amount) VALUES
(1,1,25),(2,1,15),(3,1,20),(1,2,10),(2,2,10),(3,2,5),(1,3,5),(2,3,5);
我想像这样获得PIVOT:
| Products | Process1 | Process2 | Process3 |
| Product1 | 15 | 5 | 5 |
| Product2 | 5 | 5 | 5 |
| Product3 | 15 | 5 | NULL |
您可以看到-输出不像简单的PIVOT,但我的每一个“上一个”列都减去了“下一个”列(当然,最后一列除外)...
非常感谢! :)
答案 0 :(得分:2)
您可以使用条件聚合:
select lpr.name,
sum(case when p.processid = 1 then p.amount when p.processid = 2 then -p.amount end) as process1,
sum(case when p.processid = 2 then p.amount when p.processid = 3 then -p.amount end) as process2,
sum(case when p.processid = 3 then p.amount end) as process3
from production p join
listproducts lpr
on p.productid = lpr.productid join
listprocesses lpro
on p.processid = lpro.processid
group by lpr.name;
Here是db <>小提琴。
答案 1 :(得分:0)
您可以像使用PIVOT
和LEAD
一样编写查询。
select [name] as Products, Process1, Process2, Process3
from (select t1.Name,
t2.amount - Isnull((Lead(t2.amount)
over(partition by T2.productid
order by t2.processid ) ), 0) amount,
t3.Name as ProcesName
from listproducts t1
inner join production t2
ON t1.productid = t2.productid
inner join listprocesses t3
ON t3.processid = t2.processid) t
pivot ( max(amount)
for procesname in ([Process1],
[Process2],
[Process3]) ) pvt
答案 2 :(得分:0)
您可以在下面使用lead()函数进行尝试
with cte as
(
select *,case when processname<>'process3' then
amount-coalesce(lead(amount) over(partition by productname order by processname),0) else amount end as amt from
(
select b.name as productname, c.name as processname,amount
from Production a
inner join ListProducts b on a.productid=b.ProductID
inner join ListProcesses c on a.ProcessID=c.ProcessID
)A
)
select productname, max(case when processname='Process1' then amt end) as process1,
max(case when processname='Process2' then amt end) process2,
max(case when processname='Process3' then amt end) process3
from cte
group by productname
输出:
productname process1 process2 process3
Product1 15 5 5
Product2 5 5 5
Product3 15 5