2012-11-30 1 views
5

Questo è esempio di query:come ottenere il valore della query da 1 riga da utilizzare su un'altra riga?

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

Il COSTO ho ha 3 elementi Cost_Type che hanno una propria Cost_value.

voglio manipolare in questo modo:

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 

Il punto è la voglio divise il payment_value in ciascun cost_value. Nell'esempio lo payment_by_cost diventa 40, 40, 20 = 100.

Il laboratorio cost_value è 40 ma può assegnare il valore è 20 perché rimane dal tipo di costo diviso 2 sopra.

È possibile che sia possibile utilizzare il valore da Payment_by_cost_type nel record della riga successiva? Ho cercato di inserire il valore Payment_by_cost_type in una tabella temporanea ma selezionare non può avere un'istruzione di inserimento.

Qualcuno ha qualche idea su come risolvere questo? Ho consultato DWH dicendo che deve utilizzare la procedura Store che non può essere eseguita tramite query.

risposta

2

Credo che la tabella contiene non solo "di spesa I", ma altri valori: ecco una query per risultati di output per tutti i gruppi (di Payment_type) nella tabella:

;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

è necessario definire un qualche tipo di ordine per i record di definire l'ordine in cui i pagamenti devono essere applicate

Una volta che avete fatto (sto usando ID in questo esempio) ...

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

Farlo passo dopo passo utilizzando le espressioni di tabella comuni.

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 

Demo on SQLFiddle