2012-11-30 34 views
5

Đây là ví dụ truy vấn:cách nhận giá trị truy vấn từ 1 hàng để sử dụng cho hàng khác?

payment_Type payment_value  cost_type  cost value 
Cost I   100     Registration  40 
Cost I   100     books    40 
Cost I   100     Lab    40 

Các CHI PHÍ tôi có 3 yếu tố Cost_Type có của mình Cost_value.

Tôi muốn thao tác như thế này:

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 

Vấn đề là tôi muốn chia payment_value vào mỗi cost_value. Trong ví dụ, số payment_by_cost trở thành 40, 40, 20 = 100.

Phòng thí nghiệm cost_value là 40 nhưng có thể gán giá trị là 20 vì vẫn còn từ loại chi phí chia 2 ở trên.

Có thể tôi có thể sử dụng giá trị từ Payment_by_cost_type trong bản ghi hàng tiếp theo không? Tôi đã cố gắng chèn giá trị Payment_by_cost_type vào bảng tạm thời nhưng chọn không thể có câu lệnh chèn.

Có ai có bất kỳ ý tưởng nào về cách giải quyết vấn đề này không? Tôi đã được tư vấn cho DWH ông nói nó phải sử dụng thủ tục Store nó không thể thực hiện bằng truy vấn.

Trả lời

2

Tôi đoán bảng của bạn có chứa không chỉ "Chi phí I" nhưng giá trị khác vì vậy đây là một truy vấn đến kết quả đầu ra cho tất cả các nhóm (bằng Payment_type) trong bảng:

;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; 

SQLFIDDLE demo

1

Bạn cần phải xác định một số loại trật tự để làm hồ sơ để xác định, trong đó đặt hàng các khoản thanh toán nên được áp dụng

Một khi bạn đã làm điều đó (Tôi đang sử dụng ID trong ví dụ này) ...

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 
1

Thực hiện từng bước bằng cách sử dụng các biểu thức bảng chung.

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 
1
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 

Bản trình diễn trên SQLFiddle

Các vấn đề liên quan