Thread: how to perform a calculation based on data


Permlink Replies: 14 - Pages: 1 - Last Post: Oct 25, 2007 4:34 AM Last Post By: Volder
Morrison

Posts: 122
Registered: 10/13/06
how to perform a calculation based on data
Posted: Oct 24, 2007 5:53 AM
Click to report abuse...   Click to reply to this thread Reply
ok I have 4 columns returned in my query which can either have a value of 'FF' or null.

I want to create a fifth column with a calculation which basically states

none are populated
1 is populated
2 are populated
3 are populated
4 are populated

I was thinking something like case mixed with count, but not sure how to set it up.

shoblock

Posts: 2,715
Registered: 06/22/06
Re: how to perform a calculation based on data
Posted: Oct 24, 2007 5:55 AM   in response to: Morrison in response to: Morrison
Click to report abuse...   Click to reply to this thread Reply
well, being old school, I'd use a decode

decode(col1,'FF',1,0) + decode(col2,'FF',1,0) + ...decode(col4,'FF',1,0)
Dave Hemming

Posts: 2,509
Registered: 08/17/05
Re: how to perform a calculation based on data
Posted: Oct 24, 2007 6:03 AM   in response to: shoblock in response to: shoblock
Click to report abuse...   Click to reply to this thread Reply
and another decode for "is" or "are"....
Dmytro Dekhtyar...

Posts: 1,288
Registered: 02/07/02
Re: how to perform a calculation based on data
Posted: Oct 24, 2007 6:04 AM   in response to: Morrison in response to: Morrison
Click to report abuse...   Click to reply to this thread Reply
SQL> with t1 as
2 (select 'FF' col1 from dual
3 union all
4 select null col1 from dual
5 union all
6 select 'FF' col1 from dual
7 union all
8 select null col1 from dual
9 )
10 select col1,
11 decode(col1,
12 null,
13 'None ',
14 to_char(count(col1) over(order by rownum))) ||
15 decode(col1,
16 null,
17 ' are ',
18 decode(count(col1) over(order by rownum), 1, ' is ', ' are ')) ||
19 ' populated ' text
20 from t1
21 /

COL1 TEXT
----


FF 1 is populated
None are populated
FF 2 are populated
None are populated

SQL>


Sorry, I mixed rows and columns :-(

Message was edited by:
Dmytro Dekhtyaryuk
shoblock

Posts: 2,715
Registered: 06/22/06
Re: how to perform a calculation based on data
Posted: Oct 24, 2007 6:06 AM   in response to: Dave Hemming in response to: Dave Hemming
Click to report abuse...   Click to reply to this thread Reply
I thought I'd leave something for the OP to do
Morrison

Posts: 122
Registered: 10/13/06
Re: how to perform a calculation based on data
Posted: Oct 24, 2007 6:06 AM   in response to: Morrison in response to: Morrison
Click to report abuse...   Click to reply to this thread Reply
and I actually need a 6th column with each of the column headers where the result is not null

such as if col1 and col2 are not null, then this column would have the headers in it (col1, col2)

Message was edited by:
user536503
BluShadow

Posts: 12,877
Registered: 09/21/05
Re: how to perform a calculation based on data
Posted: Oct 24, 2007 6:07 AM   in response to: Morrison in response to: Morrison
Click to report abuse...   Click to reply to this thread Reply
Many, many ways of doing it...

SQL> ed
Wrote file afiedt.buf
 
  1  with t as (select 'FF' as col1, null as col2, null as col3, null as col4 from dual union all
  2             select 'FF', 'FF', 'FF', null from dual union all
  3             select 'FF', 'FF', null, 'FF' from dual union all
  4             select 'FF', null, 'FF', null from dual)
  5  -- END OF TEST DATA
  6  select col1, col2, col3, col4, length(col1||col2||col3||col4)/2 as populated
  7* from t
SQL> / 
 
CO CO CO CO  POPULATED
-- -- -- -- ----------
FF                   1
FF FF FF             3
FF FF    FF          3
FF    FF             2
 
SQL>
BluShadow

Posts: 12,877
Registered: 09/21/05
Re: how to perform a calculation based on data
Posted: Oct 24, 2007 6:09 AM   in response to: Morrison in response to: Morrison
Click to report abuse...   Click to reply to this thread Reply
and I actually need a 6th column with each of the
column headers where the result is not null

Based on the given examples you should be able to figure that one out for yourself.
Morrison

Posts: 122
Registered: 10/13/06
Re: how to perform a calculation based on data
Posted: Oct 24, 2007 7:50 AM   in response to: shoblock in response to: shoblock
Click to report abuse...   Click to reply to this thread Reply
the simple decode returns only zeros
shoblock

Posts: 2,715
Registered: 06/22/06
Re: how to perform a calculation based on data
Posted: Oct 24, 2007 8:01 AM   in response to: Morrison in response to: Morrison
Click to report abuse...   Click to reply to this thread Reply
prove it!

with t as (select 'FF' as col1, null as col2, null as col3, null as col4 from dual union all
     select 'FF', 'FF', 'FF', null from dual union all
     select 'FF', 'FF', null, 'FF' from dual union all
     select 'FF', null, 'FF', null from dual)
select t.*, decode(col1,'FF',1,0) + decode(col2,'FF',1,0) + decode(col3,'FF',1,0)+decode(col4,'FF',1,0) cnt
from t
/ 
 
CO CO CO CO        CNT
-- -- -- -- ----------
FF                   1
FF FF FF             3
FF FF    FF          3
FF    FF             2
 
4 rows selected.
 
Dmytro Dekhtyar...

Posts: 1,288
Registered: 02/07/02
Re: how to perform a calculation based on data
Posted: Oct 24, 2007 8:06 AM   in response to: shoblock in response to: shoblock
Click to report abuse...   Click to reply to this thread Reply
We can also use the fact, that FF is one valid value for column

SQL> with t as (select 'FF' as col1, null as col2, null as col3, null as col4 from dual union all
2 select 'FF', 'FF', 'FF', null from dual union all
3 select 'FF', 'FF', null, 'FF' from dual union all
4 select 'FF', null, 'FF', null from dual)
5 select length(col1||col2||col3||col4) / 2
6 from t
7 /

LENGTH(COL1||COL2||COL3||COL4)


1
3
3
2

SQL>

:-)

William Robertson

Posts: 6,652
Registered: 06/17/98
Re: how to perform a calculation based on data
Posted: Oct 24, 2007 8:28 AM   in response to: BluShadow in response to: BluShadow
Click to report abuse...   Click to reply to this thread Reply
Just for fun:

with t as (select 'FF' as col1, null as col2, null as col3, null as col4 from dual union all
select 'FF', 'FF', 'FF', null from dual union all
select 'FF', 'FF', null, 'FF' from dual union all
select 'FF', null, 'FF', null from dual)
select col1, col2, col3, col4
, ( select count(*)
from table(sys.dbms_debug_vc2coll(col1,col2,col3,col4))
where column_value is not null ) AS populated#1
, nvl2(col1,1,0) + nvl2(col2,1,0) + nvl2(col3,1,0) + nvl2(col4,1,0) AS populated#2
, nvl2(col1,'Col1 ',null) || nvl2(col2,'Col2 ',null) || nvl2(col3,'Col3 ',null) || nvl2(col4,'Col4',null)
AS column_list
from t;

CO CO CO CO POPULATED#1 POPULATED#2 COLUMN_LIST
-- -- -- --
-----------
FF 1 1 Col1
FF FF FF 3 3 Col1 Col2 Col3
FF FF FF 3 3 Col1 Col2 Col4
FF FF 2 2 Col1 Col3

4 rows selected.
Morrison

Posts: 122
Registered: 10/13/06
Re: how to perform a calculation based on data
Posted: Oct 24, 2007 10:21 AM   in response to: shoblock in response to: shoblock
Click to report abuse...   Click to reply to this thread Reply
you are correct....when I strip out the extras it works fine.

the problem is that I need some additional columns returned and the four columns I previously mentioned were decoded from other results.

query is as such now(without the calculation requested):

select
vdh.vin as VIN,
mcs.vehicle.veh_manuf_year@OCP5 as YEAR,
mcs.veh_make.veh_make_desc@OCP5 as MAKE,
vcbc.veh_model.veh_model_desc@OCP5 as MODEL,
vdh.created_timestamp as "TIMESTAMP",
max(to_char(decode(c.COMMAND_ID,'LT_FT_TR_PR',TRIM (TO_CHAR
(cvp.command_result, 'XXXXXXXXXXXXXXX')), ' '))) LF_TIRE_PRESSURE,
max(to_char(decode(c.COMMAND_ID,'RT_FT_TR_PR',TRIM (TO_CHAR
(cvp.command_result, 'XXXXXXXXXXXXXXX')), ' '))) RF_TIRE_PRESSURE,
max(to_char(decode(c.COMMAND_ID,'LT_RR_TR_PR',TRIM (TO_CHAR
(cvp.command_result, 'XXXXXXXXXXXXXXX')), ' '))) LR_TIRE_PRESSURE,
max(to_char(decode(c.COMMAND_ID,'RT_RR_TR_PR',TRIM (TO_CHAR
(cvp.command_result, 'XXXXXXXXXXXXXXX')), ' '))) RR_TIRE_PRESSURE,
max(to_char(decode(c.COMMAND_ID,'HIGH__PRESSURE_LIMIT',TRIM (TO_CHAR
(cvp.command_result, 'XXXXXXXXXXXXXXX')), ' '))) HI_LIMIT,
max(to_char(decode(c.COMMAND_ID,'LOW__PRESSURE_LIMIT',TRIM (TO_CHAR
(cvp.command_result, 'XXXXXXXXXXXXXXX')), ' '))) LO_LIMIT,
c.STATUS as STATUS,
dh.DTC_CODE as DTC_CODE,
dh.EXPLANATION_TEXT as DTC_EXPLANATION,

with t as (select 'FF' as LF_TIRE_PRESSURE, null as RF_TIRE_PRESSURE,
null as LR_TIRE_PRESSURE, null as RR_TIRE_PRESSURE from dual union all
select 'FF', 'FF', 'FF', null from dual union all
select 'FF', 'FF', null, 'FF' from dual union all
select 'FF', null, 'FF', null from dual) select t.*,
decode(LF_TIRE_PRESSURE,'FF',1,0) + decode(RF_TIRE_PRESSURE,'FF',1,0) +
decode(LR_TIRE_PRESSURE,'FF',1,0)+decode(RR_TIRE_PRESSURE,'FF',1,0) cnt
from t

from vdu.c2pt_data_history c, veh_diag_history vdh,
vdu.connected_veh_param cvp,
module_history mh, dtc_history dh,
mcs.vehicle@OCP5, mcs.veh_make@OCP5, vcbc.veh_model@OCP5,
vcbc.veh_manufacturer@OCP5

where ((c.VEH_DIAG_HISTORY_SAK = vdh.VEH_DIAG_HISTORY_SAK)
and (vdh.CASE_SAK = cvp.CASE_SAK)
and (dh.MODULE_HISTORY_SAK = mh.MODULE_HISTORY_SAK)
and (vdh.VEH_DIAG_HISTORY_SAK = mh.MODULE_HISTORY_SAK)
and (cvp.VEHICLE_SAK = vehicle.vehicle_sak@OCP5)
and (veh_make.veh_manuf@OCP5 = veh_model.veh_manuf@OCP5)
AND (veh_make.veh_make@OCP5 = veh_model.veh_make@OCP5)
AND (veh_manufacturer.veh_manuf@OCP5 = veh_model.veh_manuf@OCP5)
AND (veh_model.veh_manuf@OCP5 = vehicle.veh_manuf@OCP5)
AND (veh_model.veh_make@OCP5 = vehicle.veh_make@OCP5)
AND (veh_model.veh_model@OCP5 = vehicle.veh_model@OCP5)
AND (veh_model.veh_manuf_year@OCP5 = vehicle.veh_manuf_year@OCP5))

and c.CREATED_TIMESTAMP >= to_date ('10/20/2007 12:00:00 AM','MM/DD/YYYY
HH:MI:SS AM')
and c.CREATED_TIMESTAMP < to_date ('10/21/2007 12:00:00 AM','MM/DD/YYYY
HH:MI:SS AM')
group by vdh.vin, mcs.vehicle.veh_manuf_year@OCP5,
mcs.veh_make.veh_make_desc@OCP5,
vcbc.veh_model.veh_model_desc@OCP5, vdh.created_timestamp, c.STATUS,
dh.DTC_CODE,
dh.EXPLANATION_TEXT
order by vdh.created_timestamp

William Robertson

Posts: 6,652
Registered: 06/17/98
Re: how to perform a calculation based on data
Posted: Oct 24, 2007 12:04 PM   in response to: Morrison in response to: Morrison
Click to report abuse...   Click to reply to this thread Reply
You don't need to repeat the dblink everywhere.

Normally you would write something like

SELECT t.somecol
FROM vcbc.veh_model.veh_model_desc@OCP5 t
WHERE t.somekey = whatever;
Volder

Posts: 986
Registered: 04/14/07
Re: how to perform a calculation based on data
Posted: Oct 25, 2007 4:34 AM   in response to: Morrison in response to: Morrison
Click to report abuse...   Click to reply to this thread Reply
If you're not looking for easy solutions you can use collections here:

SQL> select col1, col2, col3, col4,
  2         cardinality(cast(multiset(select decode(level, 1, col1, 2, col2, 3, col3, 4, col4) from dual
  3              connect by level <= 4) as test)
  4         multiset except all
  5         cast(multiset(select null from dual connect by level<=4) as test)) coll from t
  6  / 
 
COL1       COL2       COL3       COL4             COLL
---------- ---------- ---------- ---------- ----------
FF         NULL       NULL       NULL                1
FF         FF         FF         NULL                3
FF         FF         NULL       FF                  3
FF         NULL       FF         NULL                2


detailed description in my blog:
http://volder-notes.blogspot.com/2007/10/using-collections-with-10g-features.html
Legend
Guru Guru : 2500 - 1000000 pts
Expert Expert : 1000 - 2499 pts
Pro Pro : 500 - 999 pts
Journeyman Journeyman : 200 - 499 pts
Newbie Newbie : 0 - 199 pts
Oracle ACE Director
Oracle ACE Member
Oracle Employee ACE
Helpful Answer (5 pts)
Correct Answer (10 pts)

Point your RSS reader here for a feed of the latest messages in all forums