Compounding using previous row values
Greetings!
Im trying to write SQL in Oracle 10.2.0.4. I have no success using OVER , PARTITION analytic functions. Can someone help with this requirement..
Data :
with t as (select 1 AS Calc_Seq, 700 as erncd, 0.05 as pct, 22 Hrly from dual union all
select 2, 701, 0.05 , 22 from dual union all
select 3, 702, 0.075 , 22 from dual)
SELECT T.Calc_Seq,T.erncd,T.pct,T.hrly FROM T;
Output required as follows ...
Need compounded rate field, as PCT rate of previous row "Compounded rate" field value.
CALC_SEQ ERNCD PCT HRLY Compounded rate
1 700 0.05 22 23.1
2 701 0.05 22 24.255
3 702 0.075 22 26.074125Thanks in advance.
Edited by: Rama on Jan 9, 2013 11:39 AM
Edited by: Rama on Jan 9, 2013 11:50 AM
Hi,
Try this:
WITH
t AS
SELECT 1 AS Calc_Seq ,700 AS erncd ,0.05 AS pct ,22 Hrly FROM dual UNION ALL
SELECT 2 ,701 ,0.05 ,22 FROM dual UNION ALL
SELECT 3 ,702 ,0.075 ,22 FROM dual
SELECT
FROM
T
model
dimension by (calc_seq)
measures (erncd, pct, hrly, 0 cr)
rules
cr[any] order by calc_seq = case when cv(calc_seq) = 1 then hrly[cv(calc_seq) ] * (1 +pct[cv(calc_seq)])
else cr[ cv() -1] * (1 + pct[cv()]) end
CALC_SEQ ERNCD PCT HRLY CR
1 700 0.05 22 23.1
2 701 0.05 22 24.255
3 702 0.075 22 26.074125 Regards,
Peter
Similar Messages
-
Compare previous row values for the same id and decide
Hello ,
I have this sample data
create table #student_academic
pk_id int identity(1,1) primary key ,
student_id int ,
[year] int,
[aggr_marks] float
insert into #student_academic
student_id ,
[year] ,
[aggr_marks]
values
(112,2012,55.4),(113,2012,65.4),(114,2012,82.32),
(112,2013,75.4),(113,2013,91.22),(114,2013,45.45),
(112,2014,61.2),(113,2014,95.2),(114,2014,75.6)
select * from #student_academic
from the above data i have to generate an extra status column. this status column should be decided by comparing the previous row value. the exact output should be like below.
student_id year aggr_marks Staus----------------------------------------------------------
112 2012 55.4 None
112 2013 75.4 Promoted
112 2014 61.2 Demoted
113 2012 95.2 None
113 2013 75.6 Demoted
113 2014 91.22 Promoted
113 2012 45.45 None
113 2013 65.4 Promoted
113 2014 82.32 Promoted
is there any way to write the t-sql with out using cursors ? this table has around 25GB of data. Any idea would be appreciated.
Thanks in advance.Hello,
The difficulty of your example is
that there are several rows for
the same year and the same student.
I present a solution
if there is
one line per year per
student:
TRUNCATE TABLE #student_academicinsert into #student_academic
student_id ,
[year] ,
[aggr_marks]
values
(112,2012,55.4),(113,2012,65.4),(114,2012,82.32),
(112,2013,75.4),(113,2013,91.22),(114,2013,45.45),
(112,2014,61.2),(113,2014,95.2),(114,2014,75.6)
Go
WITH CTE AS
(SELECT pk_id, student_id, year, aggr_marks,
(SELECT TOP 1 aggr_marks FROM #student_academic AS b
WHERE a.student_id = b.student_id AND a.year -1 = b.year
ORDER BY student_id) AS prev_aggr_marks
FROM #student_academic AS a
SELECT
pk_id, student_id, year, aggr_marks,
CASE
WHEN prev_aggr_marks IS NULL THEN 'None'
WHEN aggr_marks < prev_aggr_marks THEN 'Demoted'
WHEN aggr_marks >= prev_aggr_marks THEN 'Promoted'
END AS Status
FROM CTE
ORDER BY student_id, year
Regards,
Charlie
Charlie Dancoisne - Independent Consultant & Trainer (Please take a moment to "Vote as Helpful" and/or "Mark as Answer", where applicable. This helps the community, keeps the forums tidy, and recognises useful contributions. Thanks!) -
How to propogate previous row value
All,
I have a query were I need to fill the null data with previous row value. Like I have a table were we record all the On hand quantity for a item for a date. Lets say I have only 2 rows in this table for a month then I am planning to write a view that will give me 31/30 rows for a month and if for a specific date is the value is null then it should read from previous row unitl it finds the data otherwise display 0.
Ex. Actual table
Item No Date Qty
1 1/1/2010 10
1 1/5/2010 15
View I have written, I need to fill the null Qty with previous row data
Item No Date Qty
1 1/1/2010 10
1 1/2/2010
1 1/3/2010
1 1/4/2010
1 1/5/2010 15
1 1/6/2010
I want something like this how can i do this?
Item No Date Qty
1 1/1/2010 10
1 1/2/2010 10
1 1/3/2010 10
1 1/4/2010 10
1 1/5/2010 15
1 1/6/2010 15
ThanksHi Sung, sorry by my delay
Basically I'm building a Client Framework that a lot of actions are automatically managed, then I extend Objects
for example EntityImpl. I let to user set any value to the
database mapped fields but I will check this values
using my own bussines rules before to insert into database
and if this values are wrong I display an alert.
My problem is that I catch insert event to call validate
functions. But when any value is wrong I will show an alert, but if user commits transaction after validate
funcion is not revalidated. Well I supose that is a bad implementation for validation rules, now amb reading about
Validationlistener because I think is the best way to do
all that I need. I let to the user add field values but
these values not will commited while validationListeners
return isValid = true;
Thanks Sung.
Albert. -
DAX - how to use dax to return a previous row value?
Hi,
I was trying to use the EARLIER function but couldn't make it work:
EVALUATE
SUMMARIZE (
CALCULATETABLE (
'Inscricoes',
'Ano Letivo'[ID_TB_DIM_ANO_LETIVO] <= VALUE(26),
'Ano Letivo'[ID_TB_DIM_ANO_LETIVO] > VALUE(26) - 5,
'Escola'[ID_TB_DIM_UNIDADE_ORGANICA] = VALUE(6),
Curso[ID_TB_DIM_CURSO] = VALUE(372),
'Tipo de Inscricao no Curso'[DS_TIPO_INSCRICAO_CURSO]
= "Matrícula"
'Ano Letivo'[ID_TB_DIM_ANO_LETIVO],
'Ano Letivo'[DS_ANO_LETIVO],
"NR_INSCRICOES", [NR_ESTUDANTES_INSCRITOS])
This generates:
ID_TB_DIM_ANO_LETIVO
DS_ANO_LETIVO
NR_INSCRICOES
22
2010-11
93
23
2011-12
101
24
2012-13
84
25
2013-14
85
26
2014-15
104
I need a new field that does returns the previous value of subscriptions (NR_INSCRICOES), so last 2 columns will be:
93 -
101 - 93
84 - 101
85 - 84
104 - 85
Need some help. ThanksHi Pedro,
According to your description, you want to get the previous row data along with each row. Right?
In DAX, we can use EARLIER() function to achieve this requirement. Please refer to link below:
PowerPivot DAX Session Notes 2 – Previous Row
In this scenario, I suggest you select the three columns into one table(let's say TABLE1). Then you can try the expression below:
=CALCULATE(MAX(TABLE1[NR_ESTUDANTES_INSCRITOS]), (FILTER(TABLE1,EARLIER(TABLE1[ID_TB_DIM_ANO_LETIVO])>TABLE1[ID_TB_DIM_ANO_LETIVO])))
Reference:
EARLIER Function (DAX)
Best Regards,
Simon Hou
TechNet Community Support -
Bulk collect seems to retain previous row value when current returns null
Dear all,
I am currently writing package in plsql.
The main logic of the program is as follow .. Program works fine .. but ... when no data is found for current V_1, V_2,V_3 , insertion is done with previous cursor row value of V_1,V_2,V_3, ... which is not good.
I tried to change the last nested cursor with first..last instead of 1..count, but result is the same.
Any idea?
open c_trt;
loop
fetch c_trt bulk collect into bk_trig limit v_limit;
open c_bkeve;
fetch c_bkeve bulk collect into bk_eve limit v_limit;
if bk_eve.count > 0 then
for k in 1..bk_eve.count loop;
case
when a =1 then
open c_bkieve(bk_eve(k).age,bk_eve(k).ope, bk_eve(k).eve);
fetch c_bkieve bulk collect into bk_ieve limit v_limit;
if bk_ieve.count > 0 then
for j in 1..bk_ieve.count loop
fetch c_bkieve bulk collect into bk_ieve limit v_limit;
if bk_ieve.count > 0 then
for j in 1..bk_ieve.count loop
case bk_ieve(j).a
when 'ABC' then
V_1 := nvl(trim(bk_ieve(j).b),null);
when 'XYZ' then
V_2 := nvl(trim(substr(bk_ieve(j).b,1,4)),null);
V_3 := nvl(trim(substr(bk_ieve(j).b,6,22)),null);
else
null;
end case;
end loop;
else
V_1 := null;
V_2 := null;
V_3 := null;
end if;
close c_bkieve;
insert into xxx values(V_1,V_2,V_3);
etc, etc
Thanks for your help
JeromeSomething like this
select a.dco
, a.agsa
, a.agem
, a.agde
, a.ope
, a.eve
, a.tpr
, a.nat
, a.age
, a.dev
, a.ncp
, a.suf
, a.sen
, a.dva
, a.mon
, a.lib
, c.cli
from bmvtg_mi a
join bcom c
on a.age = c.age
and a.dev = c.dev
and a.ncp = c.ncp
and a.suf = c.suf
join (
select x.*
, y.cur_char
from bkeve_mi x
left join wb_currency y
on x.csp4 = y.cur_num
) b
on b.age = decode(v_var1, 'age', a.age, 'agem', a.agem, 'agsa', a.agsa, 'agde', a.agde, a.age)
where exists
select *
from wb_client sc
where c.cli = sc.customer_number
and ready = 1
and exists
select *
from wb_pdt sp
where c.cpro = sp.c_pro -
Populate other column value based on previous row value using t-sql
Hi All,
I have one table with 6 columns, let say ID1, ID2,status, EnteredDate,NewValue, Old Value. Where ID1 is the primary key field
ID1 ID2 status EnteredDate NewValue
Old Value
1 XYZ New 07/12/2012
ABC null
2 XYZ Renewal 08/19/2012 DEF
null
3 XYZ Cancel 10/21/2012 GHI
null
4 ZYX New 09/15/2012
BDF null
5 ZYX Cancel 10/21/2012 MNS
null
6 MBS New 05/29/2012
EXP null
7 SBX New 05/29/2012
SKS null
8 SBX Renewal 06/21/2012 QSR
SKS
Basically I need a sql query which should populate Output as below. Status=New will always have old date compared to Renewal and Cancel and also OldValue field will be null always for status=New
Output:
ID1 ID2 status EnteredDate NewValue
Old Value Row_Num(based on ID1,ID2,Entereddate)
1 XYZ New 07/12/2012
ABC null 1
2 XYZ Renewal 08/19/2012 DEF
ABC 2
3 XYZ Cancel 10/21/2012 GHI
DEF 3
4 ZYX New 09/15/2012
BDF null 1
5 ZYX Cancel 10/21/2012 MNS
BDF 2
6 MBS New 05/29/2012
EXP null 1
7 SBX New 05/29/2012
SKS null 1
8 SBX Renewal 06/21/2012 QSR
SKS 2
Thanks in Advance, its very urgent. Pls send me the query ASAP.
RH
sqlHi,
In case of you are using SQL 2012, you can use new built-in function like LAG, try this;
USE tempdb
GO
CREATE TABLE dbo.Test
ID1 int PRIMARY KEY
, ID2 char(3) NOT NULL
, Status varchar(20) NOT NULL
, EnteredDate date NOT NULL
, NewValue char(3) NOT NULL
, OldValue char(3) NULL
GO
INSERT INTO dbo.Test
(ID1, ID2, Status, EnteredDate, NewValue, OldValue)
VALUES
(1, 'XYZ', 'New', '07/12/2012', 'ABC', null)
, (2, 'XYZ', 'Renewal', '08/19/2012', 'DEF', null)
, (3, 'XYZ', 'Cancel', '10/21/2012', 'GHI', null)
, (4, 'ZYX', 'New', '09/15/2012' ,'BDF', null)
, (5, 'ZYX', 'Cancel', '10/21/2012', 'MNS',null)
, (6, 'MBS', 'New', '05/29/2012', 'EXP', null)
, (7, 'SBX', 'New', '05/29/2012', 'SKS', null)
, (8, 'SBX', 'Renewal', '06/21/2012', 'QSR', 'SKS')
WITH cte
AS
(SELECT ID1, ID2, Status, EnteredDate, NewValue, OldValue
, ROW_NUMBER() OVER(PARTITION BY ID2 ORDER BY ID2) Row_Num
, LAG(NewValue, 1, 0) OVER(PARTITION BY ID2 ORDER BY ID2) NewOldValue
FROM dbo.Test)
SELECT ID1, ID2, Status, EnteredDate, NewValue
, NULLIF(NewOldValue, '0') NewOldValue, Row_Num
FROM cte
ORDER BY ID1, ID2;
Dinesh Priyankara
http://dinesql.blogspot.com/
Please use Mark as answer (Or Propose as answer) or Vote as helpful if the post is useful. -
Query! calculation based on previous row value
Hi,
ID Code Direction From Amount To Perct To Amount
98 POI F 5457.00 0
77 LKJ T 0 50 (5457*(50/100))
56 MNB T 0 25 (5457*(25/100))How to calculate 'To Amount' with in the select query? To Amount will be calculated on the basis of
From Amount of the First row multiplied by 'To Perct'
When I wrote a select statement it's taking 0 as 'From Amount'( Because it's in current row) and giving me 0 as 'To Amount'
ThanksOne possibility:
with t as (
select 98 id, 'POI' Code, 'F' Direction, 5457.00 FromAmount, 0 ToPerct from dual union all
select 77, 'LKJ', 'T', 0, 50 from dual union all
select 56, 'MNB', 'T', 0, 25 from dual)
select id, code, direction, FromAmount, ToPerct,
(tmax.MaxAmount)*(ToPerct/100) ToAmount
from t,
(select max(FromAmount) MaxAmount from t) tmax ;Results:
ID COD D FROMAMOUNT TOPERCT TOAMOUNT
98 POI F 5457 0 0
77 LKJ T 0 50 2728,5
56 MNB T 0 25 1364,25Regards,
Miguel -
Find the difference between previous row value
Hi All,
I have a Property Rent Review table which holds the last rent update done on a property.
I need to be able to compare the rent change (%) at any interval for a property. - so the query should allow to pull the property rent at 2 or more points in time and I need a view that shows % increase or decrease between the 2 dates.
Generally the dates would be 3 months apart (qtrly) but I would like to be able to enter my own dates in case I want to run monthly / annually or compare “before” and “after” the Rent Review.
Below is a sample data
TenantCode PropCode Rent Charged Rent Change Date
31163 2469 157.68 6/01/2014
31163 2469 160.69 16/06/2014
31163 2469 162.65 1/12/2014
51428 2469 162.65 10/12/2014
50824 3174 160.69 28/03/2014
50824 3174 160.69 4/04/2014
50111 3174 149.5 21/05/2014
50695 3852 256.5 24/01/2014
50695 3852 327.87 10/03/2014
50695 3852 256.6 31/03/2014
50804 3865 278.48 18/03/2014
50779 3865 236.67 21/05/2014
50804 3865 237.82 31/07/2014
51135 3865 237.82 21/08/2014
51135 3865 165.69 12/09/2014
51135 3865 230.15 17/11/2014Hi Diegoctn,
Your query work perfectly. But can we get the view as Patricks view below
With
CTE
AS
SELECT
ROW_NUMBER()OVER
(PARTITIONBYProp_Code
ORDERBYDATE_CHANGED_SQL)ASSeq,
FROM
R23
SELECT
c1.PROP_CODE,c1.TENANT_NUMB,c1.TOT_DEB_VAL,c1.DATE_CHANGED_SQL,(c1.TOT_DEB_VAL
-c2.TOT_DEB_VAL)*100.0/NULLIF(c2.TOT_DEB_VAL,0)
AS[Rent(%)]
FROM
CTE c1
LEFT
JOINCTE
c2
ON
c1.PROP_CODE
=c2.PROP_CODE
AND
c1.Seq
=c2.Seq
+1
Where
c1.PROP_CODE
='1587' -
I have a SSRS report which uses a matrix for a crosstab effect.
Each row contains about 10 score values in 10 columns respectively. I need each row to check against the previous row, and i need each score value in each column to be compared to the corresponding column score value in the previous row.
If the current score is greater than the corresponding previous score (in the previous row), then i want to change the background of the cell.
if the current score is smaller than the previous, then it's a different color.
if they are equal, or it's the first row in the matrix table, then leave white.
I have found custom code functions to use in the SSRS expression fields, but every single one of them compares against the previous COLUMN value and not the previous ROW value which is what i need. the "Previous" function would be perfect if i
could use it in a matrix but i can't. (i keep getting error "The use of a Previous aggregate function in a tablix cell is not supported"). looking around it turns out that matrices are arrange in groups and not in rows which is why Previous can't
be used and the only way is with custom code.
Please help. if you have any custom code samples that achieve what i need, please share, or give me advice on how to achieve this.
Thank youI figured it out. Maybe it can help someone else in the future:
Public Shared count as Integer = 0
Public Shared currentRow As Integer = 1
Public Shared MatrixStructures As New System.Collections.Generic.List(Of MatrixStructure)()
Public Shared Function GetCellColor(row as Integer, score as Integer)
If (row > currentRow) Then
count = 0
currentRow = row
End If
count = count + 1
Dim matrixStructure As New MatrixStructure()
matrixStructure.RowIndex = row
matrixStructure.ColumnIndex = count
matrixStructure.ScoreValue = score
MatrixStructures.Add(matrixStructure)
If score = 0 Then
Return "White"
End If
Dim val As MatrixStructure = MatrixStructures.Find(Function(s As MatrixStructure)
Return s.GetRowIndex() = row - 1 AndAlso s.GetColumnIndex() = count
End Function)
If (Not (val Is Nothing)) Then
If val.scoreValue = 0 Then
Return "White"
End If
If score >= val.scoreValue + 2 Then
Return "Green"
ElseIf score <= val.scoreValue - 2 Then
Return "Red"
End If
End If
Return "White"
End Function
Public Class MatrixStructure
Public rowIndex As Integer
Property GetRowIndex() As Integer
Get
Return rowIndex
End Get
Set(ByVal Value As Integer)
rowIndex = Value
End Set
End Property
Public columnIndex As Integer
Property GetColumnIndex() As Integer
Get
Return columnIndex
End Get
Set(ByVal Value As Integer)
columnIndex = Value
End Set
End Property
Public scoreValue As Integer
Property GetScoreValue () As Integer
Get
Return scoreValue
End Get
Set(ByVal Value As Integer)
scoreValue = Value
End Set
End Property
End Class
and to pass the current row number from the expression i use this
Ceiling(RowNumber(NOTHING) / 10)
i divide the row number by 10 because there are ten columns. if you don't know the number of columns, or it's a variable number, then return it from the stored procedure query in the first place. that's what I had to do -
How to get the value of column from previous row to current row?
Hi All,
I am facing a critical problem in SQL query (for reporting purpose (COGNOS)). please reply to my query.
REQUIREMENT: i want to retrive value of a column (this is not a table column, this will be calculated based expression) from previous row to current row.
EXAMPLE:
TABLE NAME: i have to join multiple tables. so, i am not mentioning table names here.
DISPLAY COLUMNS in the report: item, loc, sku, beginval (not table column), endval (not table column, this will calculated based on some expressions), etc. Here, first time the value of BEGINVAL will be taken from some x column name of x table. ENDVAL will calculated based on the expression. For the next row onwards, BEGINVAL will become the value of ENDVAL and the value of ENDVAL will be calculated based on the expression and this expression uses the value of BEGINVAL.
my report will look like below.
ITEM LOC SKU BEGINVAL ENDVAL
1 HYD 1-HYD 10 10+1+2 (13)
2 HYD 2-HYD 13 13+1+2 (16)
3 SEC 3-SEC 16 16+1+2 (19)
4 SEC 4-SEC 19 19+1+2 (22)
etc....
in the above output, BEGINVAL and ENDVAL columns are not part of any table. they are alias column names.if you observe intially BEGINVAL will be assigned to some value, but from subsequent rows, BEGINVAL will become the ENDVAL of previous row.
Please help me on how to write this query?Hi, please find the detail description of the problom.
DDL (table scripts)
ITEM
CREATE TABLE ITEM
ITEM VARCHAR2(50 CHAR) NOT NULL,
DESCR VARCHAR2(50 CHAR) DEFAULT ' ' NOT NULL,
UOM VARCHAR2(50 CHAR)
SKU
CREATE TABLE SKU
ITEM VARCHAR2(50 CHAR) NOT NULL,
LOC VARCHAR2(50 CHAR) NOT NULL,
OH float
SKUPROJSTATIC
CREATE TABLE SKUPROJSTATIC
ITEM VARCHAR2(50 CHAR) NOT NULL,
LOC VARCHAR2(50 CHAR) NOT NULL,
STARTDATE DATE
VehicleLoad
CREATE TABLE VEHICLELOAD
LOADID VARCHAR2(50 CHAR) NOT NULL,
DESCR VARCHAR2(50 CHAR) DEFAULT ' ' NOT NULL,
SHIPDATE DATE DEFAULT TO_DATE('01/01/1970','MM/DD/YYYY') NOT NULL,
ARRIVDATE DATE
VEHICLELOADLINE
CREATE TABLE VEHICLELOADLINE
LOADID VARCHAR2(50 CHAR) NOT NULL,
ITEM VARCHAR2(50 CHAR) NOT NULL,
QTY float(126)
DML scripts
I can't provide the the DML scripts, because its very huge data.
Main QUERY is below.
below is the query which i have to write and execute.
select
i.item,
i.descr,
i.unitsperpallet,
sp.loc,
sp.startdate,
'Crucial_IND',
LAG (EndBal,1,0) OVER (ORDER BY STARTDATE) BeginBal,
SP.FCSTCUSTORDERS CustOrders,
SP.COMMITINTRANSOUT,
SP.RECARRIV,
SP.TOTINTRANSIN,
(BeginBal - sp.FCSTCUSTORDERS - sp.COMMITINTRANSOUT + sp.TOTINTRANSIN ) EndBal,
'CuttingQty',
VLL.QTY,
vl.source,
vl.arrivdate,
vl.shipdate,
vl.loadid,
s.oh
from item i, skuprojstatic sp, sku s, VehicleLoad vl, VehicleLoadLine vll
where sp.item = i.item
and s.item=i.item
and sp.item =s.item (+)
and sp.loc = s.loc (+)
and vll.item = s.item
and vll.loadid = vl.loadid
and to_char(sp.startdate ,'mm/dd/yyyy') = to_char(vl.arrivdate,'mm/dd/yyyy')
and sp.loc = vl.dest (+)
order by sp.startdate
problem description: in the above query, BeginBal and EndBal is what i am looking for. when i execute this query, oracle throwing an error saying that alias names can't be used as expressions. For the first row, the BeginBal should be the value sku.OH and for the subsequent rows, this value will be the previous row value of EndBal. -
SQL Developer - Pulling column value from previous row
I am using Oracle SQL developer and trying to pull a value from a column from the previous row.
Currently this is an example from the code im using.
Select CD1.nbr_dw, CD1.SEQ_DW, CD1.CDL_NET_PAID, CD1.UNITS_ALLOW,CD1.ALLOW_AMT, CD1.UNIT_PRICE, CD1.BACKED_OUT,
case
When CD1.NET_PAID = 0 then 0
****NEW CODE*****
Else CD1.ALLOW_AMT / CD1.UNIT_PRICE
end as NEW_UNITS
From Table_A CD1
join (Select nbr_dw, DET_DW, SEQ_DW
From Table_B
) CD2
on CD1.nbr_dw = CD2.nbr_dw
I need to add another when statement that says when CD1.BACKED_OUT = 'Y' populated the NEW_UNITS field with the previous rows value of CD1.UNIT_PRICE. Note, the CD1.SEQ_DW can be used to determine the previous row. Any ideas?Hi,
Welcome to the forum!
The analytic LAG function can return a value from the previous row:
LAG (cd1.unit_price) OVER ( -- PARTITION BY x -- if needed
ORDER BY cd1.seq_dw
)It's unclear if you need a PARTITION BY clause or not.
"PARTITION BY x" means that you want the value from the last row that has the same value of x as the current row.
If you omit the PARTITION BY clause, it means you want the last row regardless of what any other columns are.
Whenever you have a problem, it ehlps if you post a little sample data (CREATE TABLE and INSERT statements) and the results you want from that data.
Explain how you get those results from that data.
Always say what version of Oracle you're using. -
Update field taking value from previous row
I have a table TEST (ID int, name varchar(20), amount decimal(18,0)).
First row of the table have correct value. I want to update amount column except first row by adding 10 with the previous row value without using cursor.
id Name Amount
1 abc 10
2 def 15
3 ghi 20
4 jkl 22
5 mno 25
6 pqr 27
7 stu 30
8 vwx 33
id Name Amount
1 abc 10
2 def 20
3 ghi 30
4 jkl 40
5 mno 50
6 pqr 60
7 stu 70
8 vwx 80
please help me.
thanks
srimanta mannacreate table #t (id int, amount int)
insert into #t values (1,10)
insert into #t values (2,25)
insert into #t values (3,46)
insert into #t values (4,55)
insert into #t values (5,160)
insert into #t values (6,89)
insert into #t values (7,100)
with cte
as
select *,(select min(amount) from #t t where t.id=1) as a
FROM #t
) update #t set amount=(select sum(a) from cte c where c.id<=cte.id)
from cte where #t.id=cte.id
select * from #t
Best Regards,Uri Dimant SQL Server MVP,
http://sqlblog.com/blogs/uri_dimant/
MS SQL optimization: MS SQL Development and Optimization
MS SQL Consulting:
Large scale of database and data cleansing
Remote DBA Services:
Improves MS SQL Database Performance
SQL Server Integration Services:
Business Intelligence -
Calculate using previous column and rows
Hello TNO members,
I have a complicated problem I need to solve, how ever I am missing knowledge about calculating using previous rows and columns in current select.
Test data
with t as (
select 1 as box, 1 as box_group, 10 as max_qty from dual union all
select 2, 1, 15 from dual union all
select 3, 1, 40 from dual union all
select 4, 1, 45 from dual union all
select 5, 2, 15 from dual union all
select 6, 2, 20 from dual union all
select 7, 2, 20 from dual union all
select 8, 3, 20 from dual)Expected Output result
box box_group max_qty assigned_from_60
1 1 10 10
2 1 15 15
3 1 40 17
4 1 45 18
5 2 15 0
6 2 20 0
7 2 20 0
8 3 20 0The problem:
In total 60 items are shared among the boxes in the same group, ordered by the lowest max_qty.
10 items can be assign to each box in group 1. (Used items: 40)
The remaining 20 items will be assigned to the other boxes in group 1.
5 more items can be assign to each box in group 1 (Used items: 15)
The remaining 15 items will be assigned to the remaining boxes in group 1.
2 more items can be assign to each box in group 1 (used items: 4)
One item remains. When items cannot be shared equally among the remaining boxes, ordered by the highest max_quantity, assign +1 till no item remains.
My solution in steps:
1. Calculate max_qty difference. How can I calculate the difference between the max_qty from box 1 and 2? Tricky is not to calculate the difference between different groups.
This means output result should be something like
box box_group max_qty qty_dif
1 1 10 10
2 1 15 5
3 1 40 25
4 1 45 5
5 2 15 15
6 2 20 5
7 2 20 0
8 3 20 202. Remaining boxes in the same group. I want to know how many boxes are in the same group. Especially the remaining boxes when the current max_quantity is filled.
Using the following code does not result in the correct output, what is wrong or missing here?
count(*) over(partition by box_group order by max_qty asc range between current row and unbounded following) This means output result should be something like
box box_group max_qty qty_dif rem_boxes
1 1 10 10 4
2 1 15 5 3
3 1 40 25 2
4 1 45 5 1
5 2 15 15 3
6 2 20 5 2
7 2 20 0 1
8 3 20 20 13. Calculate costs. This one is faily easy rem_boxes * qty_dif (*per row*)
This means output result should be something like
box box_group max_qty qty_dif rem_boxes cost
1 1 10 10 4 40
2 1 15 5 3 15
3 1 40 25 2 50
4 1 45 5 1 5
5 2 15 15 3 45
6 2 20 5 2 10
7 2 20 0 1 0
8 3 20 20 1 204. Calculate rem_items. 60 - (rem_boxes * qty_dif of box 1) - (rem_boxes * qty_dif of box 2) - (rem_boxes * qty_dif
of box n). How can I calculate using results of previous rows? (*all, not per group*)
This means output result should be something like
box box_group max_qty qty_dif rem_boxes cost rem_items
1 1 10 10 4 40 20
2 1 15 5 3 15 5
3 1 40 25 2 50 -45
4 1 45 5 1 5 -50
5 2 15 15 3 45 -95
6 2 20 5 2 10 -105
7 2 20 0 1 0 -105
8 3 20 20 1 20 -1255. Assign full quantity. For each row check if rem_items > 0 then 1 else 0
This means output result should be something like
box box_group max_qty qty_dif rem_boxes cost rem_items assign
1 1 10 10 4 40 20 1
2 1 15 5 3 15 5 1
3 1 40 25 2 50 -45 0
4 1 45 5 1 5 -50 0
5 2 15 15 3 45 -95 0
6 2 20 5 2 10 -105 0
7 2 20 0 1 0 -105 0
8 3 20 20 1 20 -125 06. Calculate assign quantity attemp 1. Calculate assign quantity of remaining boxes per group
When assign = 1 then max_qty else pervious a_qty (*within same group*)
This means output result should be something like
box box_group max_qty qty_dif rem_boxes cost rem_items assign a_qty
1 1 10 10 4 40 20 1 10
2 1 15 5 3 15 5 1 15
3 1 40 25 2 50 -45 0 15
4 1 45 5 1 5 -50 0 15
5 2 15 15 3 45 -95 0 0
6 2 20 5 2 10 -105 0 0
7 2 20 0 1 0 -105 0 0
8 3 20 20 1 20 -125 0 0How to solve the rest, I do not know yet. Any other suggestion to solve this problem, is welcome.
Since I'm not really a professional this is what I tried till now
with z as (
select 1 as box, 1 as box_group, 10 as max_qty from dual union all
select 2, 1, 15 from dual union all
select 3, 1, 40 from dual union all
select 4, 1, 45 from dual union all
select 5, 2, 15 from dual union all
select 6, 2, 20 from dual union all
select 7, 2, 20 from dual union all
select 8, 3, 20 from dual)
select u.*,
case
when u.assign = 2 then u.max_qty
when u.assign = 1 then 0
when u.assign = 0 then 0
end as assigned_qty
from
select v.*,
case
when 60 - sum(v.max_qty) over (order by v.box_group, v.max_qty, v.box) >= 0
and v.rem_items_before >= 0 then 2
when 60 - sum(v.max_qty) over (order by v.box_group, v.max_qty, v.box) < 0
and v.rem_items_before > 0 then 1 else 0
end as assign
from
select w.*,
w.rem_items_after + w.max_qty as rem_items_before
from
select x.*,
60 - x.qty_assigned as rem_items_after
from
select y.*,
y.max_qty * y.rem_boxes as total_cost,
sum(y.max_qty) over (order by y.box_group, y.max_qty, y.box) as qty_assigned
from
select z.*,
count(*) over (partition by z.box_group order by z.max_qty, z.box asc range between current row and unbounded following) as rem_boxes
from z
) y
) x
) w
) v
) uKind regards,
Metro
Edited by: 858378 on 30-mei-2011 4:39
Edited by: 858378 on 30-mei-2011 5:05Hi, Metro,
858378 wrote:
Hello, thanks for your help so far.
The course I am in, teaches you how to use the basic pl sql language such are selecting from tables.Is it about PL/SQL or SQL?
I have learned things about
- SELECT
- FROM
- WHERE
- GROUP BY
- ORDER BY
- SUB SELECTION IN SELECT
- SUB SELECTION IN FROM
- SUM, COUNT, MIN, MAX
- CASES
- INNER, OUTER, LEFT, FULL, CROSS JOINSAll of these are parts of the SQL language, not PL/SQL.
We are now at partitioning.Are you specifically at partitioning, or iare you at a point where the book talks about analytic functions, which sometimes, but not always, have a PARTTION BY clause?
It's written in Dutch, I tried to translate it, so it might not be well written English.
Excercise 192
Distribution center 'One by one' wants to automate the distribution process.
Items are distributed to the boxes one by one. Sorry, I can't figure out what Exercise 192 is, based on just that.
It is similar to the next excercise, but this above was a lot more straight to the point.
*Excercise 193*
Distribution center 'All in one box' wants to automate the distribution process.
One of the major changes in this process is to distribute items equally to all boxes in the same group.
This means starting from the lowest quantity, assign the lowest quantity to all boxes in the same group if possible.
If this is not possible distribute the amount of items divided by the number of boxes in the same group. If the amount of items per box is lower than 1 and not 0.
Divide the remaining items per box ordered by the box with the highest quantity, till there are no items left.
When it is possible to distribute the lowest quantity to all boxes, move up to the next box in the same group.
When all boxes in the same group are filled to their maximum quantity, move up to the next group and repeat this process. ...
So Exercise 193 is what you asked yesterday, right?
A) Order the following information by box_group and max_qty as described.
B) Calculate the distribution results for 60, 120, 170 items.
When I have 60 items, the following output result should be
box box_group max_qty assigned_from_60
1 1 10 10
2 1 15 15
3 1 40 17
4 1 45 18
5 2 15 0
6 2 20 0
7 2 20 0
8 3 20 0Box 1 and 2 can be filled completely as you can fill atleast 10 to box 1,2,3,4 and an additional 5 to box 2, 3 and 4.
The last item goes to the box 4.
when I have 120 items
box box_group max_qty assigned_from_120
1 1 10 10
2 1 15 15
3 1 40 40
4 1 45 45
5 2 15 3
6 2 20 3
7 2 20 4
8 3 20 0
Based on what you posted, it seems like the following should be equally acceptable:
box box_group max_qty assigned_from_120
1 1 10 10
2 1 15 15
3 1 40 40
4 1 45 45
5 2 15 3
6 2 20 4
7 2 20 3
8 3 20 0That is, the last 10 items have to be distributed among the 3 boxes in box_group=2 as equally as possible. So one box will get 4 items and the others will get 3. The extra item will go to the box with the highest max_qty, but in this case, there is a tie: box 6 has just as much of a claim to having the highest max_qty as box 7. The line marked "***** Add if needed *****" in the query blow guarantees that, in case of a tie like this, the box with the higher box value will be considered "larger" than another box with the same max_qty.
when I have 170 items
box box_group max_qty assigned_from_170
1 1 10 10
2 1 15 15
3 1 40 40
4 1 45 45
5 2 15 15
6 2 20 20
7 2 20 20
8 3 20 5
I accidentally posted the wrong query yesterday. This is what I should have posted:
WITH cntr AS
SELECT LEVEL AS n
FROM ( SELECT MAX (max_qty) AS max_max_qty
FROM z
-- WHERE box_group = :target_box_group -- ***** Removed *****
CONNECT BY LEVEL <= max_max_qty
, got_r_num AS
SELECT z.box
, c.n
, ROW_NUMBER () OVER ( ORDER BY box_group -- ***** Added *****
, c.n
, z.max_qty DESC
, box DESC -- ***** Add if needed *****
) AS r_num
FROM cntr c
JOIN z ON c.n <= z.max_qty
-- WHERE z.box_group = :target_box_group -- ***** Removed *****
, got_assigned AS
SELECT box
, COUNT (*) AS assigned
FROM got_r_num
WHERE r_num <= :total_items
GROUP BY box
SELECT z.*, NVL (a.assigned, 0) AS assigned
FROM z
LEFT OUTER JOIN got_assigned a ON z.box = a.box
ORDER BY z.box_group
, z.max_qty
;Yesterday, I described how you need to remove 2 lines and add 1, but the code I posted was the unchanged query. The query above is what I should have posted then. Look for comments beginning "*****" above for the changes. I apologize for my mistake.
This query gets the results you posted for all 3 values of :total_items that you posted. If it doesn't work for some other value, or some other data, post the new values and the correct results you want from them, and point out where the query above is wrong.
C) Sum the maximum quantities per group
D) Get the amount of boxes in each group
E) Create a column for remaining boxes per group
F) For each distinct quantity, count the amount of boxes with this quantity
G) Calculate how many items are required to fill all boxes in the same group
H) Create a plan how to solve this distribution problem described in the introduction?
I) Solve this problem using your plan.Are these the steps that the book suggests using?
I don't understand that approach. It might be a good way to solve the problem without using a computer. It might be a good way to solve the problem using a procedural language, such as PL/SQL. It might be one way of solving the problem in SQL, but I think it will be more complicated and less efficient than what I psoted.
The approach above is iterative; that is, you repeat certain steps, with different values. For example, you distribute a certain number of items to all boxes in a box_group. The you remove the smallest box(es) from the group, and repeat, distributing the remaining items among the remianing boxes. That's not hard to do in a language like PL/SQL, where you have loops and variables. In SQL, the closest thing to that is the MODEL clause. I'm sure you could write a MODEL solution to this problem, but, if your book hasn't mentioned MODEL yet, then that's certainly not what it's expecting you to do.
Even using the approach in steps A) trhough G) above, I don't see how a PARTITION BY would help. -
Derived logical column using Row values in OBIEE11g
Hi Experts
I have a requirement whereby I need to create say 100 new logical column in obiee using the row values of one dimension.
For eg. say I have dimension values like A and B in one of the table , I need to create logical columns like C=A+B and D = A/B and E = AxB as such when the user drags this to the analysis the calculation should happen automatically.
The problem is they are in the rows and not the coulmn , so I can't do plain calculation like sales per Unit = Sales/Units - as Sales and Units are two differnet measure column.
How to achieve this in RPD.
RegdsHi
Pls. find below the examples :
You have a dimesion called KPI which has soem KPIs.
KPI Measure Values
KPI1 10
KPI2 20
KPI3 50
etc
Now I need to calulate a driven KPI i.e KPI10 which is KPI10 = KPI2/KPI3 , and I need to do that in RPD.
I know I can do it in Front end analaytics by using Pivot or Selection steps . But I want to do it in RPD.
Regds -
Using the Previous Row in a Calculator Formula
Hello. I am using the calculator to create a new channel that is a custom filtered version of an existing channel. Unfortunately, I have not been able to identify the previous row entry in the channel. To make things easier, let's say my filter is a simple averager. Here is simple pseudocode for what I want to do:
New_Channel = (Existing_Channel[n] + Existing_Channel[n-1]) / 2
where n is the current row.
This is the calculator formula I have come up with:
ch("[1]/New_Channel") = (CHD(chnRow - 1, "[1]/Existing_Channel") + ch("[1]/Existing_Channel")) / 2 + CTNV(chnRow > 1)
Unfortunately, I think chnRow only returns 0.
Obviously, I am a beginner. I am open to other approaches to creating a new channel with a custom filter.
Thanks!
Solved!
Go to Solution.Hi jbuttron,
What you need to do is to copy the channel and delete the first value from the copied channel-- then the Nth row of the original channel will line up with the (N-1)th row of the copied channel. You should also add the last value of the copied channel to the end of that channel as a new value so both channels end up with the same channel length. Now you can reference the channels with Ch("[1]/old") and Ch("[1]/new") in the channel calculator expression, assuming that the channel names are "old" and "new" respectively and that both are in the first group. You don't need a row variable in the expression now, which is good because there's no way to iterate a row variable in a channel calculator expression. The row iteration is implicit in the channel referencing Ch("[1]/new").
Brad Turpin
DIAdem Product Support Engineer
National Instruments
Maybe you are looking for
-
Why does ppi matter for web images?
Hello When placing an image in my (web/pixel) project the resolution is dependent from the set ppi. When I create a new document for web, then logically only the pixels matter. Nonetheless there's a ppi field, why? And depending what value it has, pl
-
30 GB Battery LIfe when REcording
I get about 2 hours of battery life on a fully charged 30GB iPod when recording using iTalk. Is this the best anyone else is getting? What are alternatives for recording lectures with greater battery life?
-
Srdemo doesn't work in web?
I configured OAS and I could access to my project (Jdeveloper) at the local. For instance ; when the client users use this "http:\\localhost:7777\srdemo" link, they can access the project. But I can't configure our server to web like this. What can I
-
Download dashboard reports to Excel
Dose any body know how to let the user the possibility to Download a pivot table results from the dashboard to Excel Moshe
-
All I get is a 'connecting to iTunes store and Loading...' screen. When I try to sign up, I get an error saying 'We could not complete your iTunes Store request. A unknown error occurred (-50). There was an error in the iTunes store. Please try again