Sql 如何从一行获取查询值以用于另一行?
这是一个示例查询:Sql 如何从一行获取查询值以用于另一行?,sql,database,sql-server-2008,stored-procedures,Sql,Database,Sql Server 2008,Stored Procedures,这是一个示例查询: payment_Type payment_value cost_type cost value Cost I 100 Registration 40 Cost I 100 books 40 Cost I 100 Lab 40 成本I
payment_Type payment_value cost_type cost value
Cost I 100 Registration 40
Cost I 100 books 40
Cost I 100 Lab 40
成本I有3个元素成本类型,它们有自己的成本值
我想这样操纵:
payment_Type payment_value cost_type cost value Payment_by_cost_type
Cost I 100 Registration 40 40
Cost I 100 books 40 40
Cost I 100 Lab 40 20
重点是我想把支付值分成每个成本值。在该示例中,按成本付款变成40、40、20=100
lab cost_值为40,但它可以指定值为20,因为它仍然来自上面的2分成本类型
我是否可以在下一行记录中按成本类型使用付款中的值?我一直在尝试将“按成本类型付款”的值插入到临时表中,但select不能有insert语句
有人对如何解决这个问题有什么想法吗?我一直在咨询DWH,他说它必须使用存储过程,而不能通过查询来完成 您需要为您的记录定义某种顺序,以定义付款的应用顺序 一旦你完成了,我在这个例子中使用ID
select *
, case
when payment_value-(select isnull(SUM(cost_value),0) from yourtable t2 where t2.id<t1.id)<cost_value
then payment_value-(select isnull(SUM(cost_value),0) from yourtable t2 where t2.id<t1.id)
else cost_value
end
from yourtable t1
使用公共表表达式一步一步地执行
declare @t table (
payment_type varchar(20),
payment_value int,
cost_type varchar(20),
cost_value int,
cost_id int --for the ordering
)
insert @t values
('Cost I',100,'Registration',40,1),
('Cost I',100,'books',40,2),
('Cost I',100,'Lab',40,3),
('Cost 2',100,'Registration',40,4),
('Cost 2',100,'books',50,5),
('Cost 2',100,'Lab',40,6)
--get count for each payment_type to determine last row
;with payment_value_cte(payment_type,payment_value,count) as
(
select payment_type,payment_value,COUNT(*) from @t group by payment_type,payment_value
),
--use sequential index for each row in payment type
payment_value_index_cte(
payment_type ,
payment_value,
cost_type,
cost_value,
cost_id,
row) as
(
select *,ROW_NUMBER() OVER(PARTITION BY payment_type ORDER BY cost_id) from @t --assumes order is by an id
),
--get sum of each row for payment type except last row
payment_value_sum_except_last_cte(
payment_type,
payment_value,
current_sum) as
(
select pi.payment_type,pi.payment_value,SUM(cost_value)
from payment_value_index_cte pi
inner join payment_value_cte pt on pt.payment_type = pi.payment_type
where pi.row < pt.count
group by pi.payment_type,pi.payment_value
)
select
pi.payment_type,pi.payment_value,pi.cost_type,pi.cost_value,
--if last row calculate difference, else use the cost_value
case when pi.row = pt.count then pt.payment_value - pe.current_sum else pi.cost_value end [Payment_by_cost_type]
from payment_value_index_cte pi
inner join payment_value_cte pt on pt.payment_type = pi.payment_type
inner join payment_value_sum_except_last_cte pe on pe.payment_type = pi.payment_type
我猜您的表不仅包含成本I,还包含其他值,因此这里有一个查询,用于按表中的付款类型输出所有组的结果:
;with table1 as
(select
t.*,
row_number()
OVER
(PARTITION BY payment_Type order by cost_type) rn
from t
)
,table2 as
( select t4.*,isnull((select sum(cost_value) from table1
where table1.payment_type=t4.payment_type and rn<t4.rn),0) CumSum
from table1 t4
)
select payment_type,payment_value,cost_type,cost_value,
case when cost_value+CumSum<=payment_value then cost_value
else
payment_value-Cumsum
end
from table2
order by Payment_type,rn;
演示
SELECT payment_Type, payment_value, cost_type, cost_value,
CASE WHEN ROW_NUMBER() OVER (ORDER BY(SELECT 1)) = COUNT(*) OVER (PARTITION BY payment_Type)
THEN SUM(cost_value) OVER (PARTITION BY payment_Type) - payment_value
ELSE cost_value END AS Payment_by_cost_type
FROM dbo.your_table