Interview with case/when &; sum() over (partition) producing unexpected lines
Since some time ago, I asked a question in this forum on an unusual problem of join and subtract ( subtract the total periods of highest level duration ). I had what seemed like a work request. So far, I could not really use it. Now that I'm looking closer results, I think that there is something wrong with it, but I can't understand why it's happening.Using the definition of the table of the original question, the following simple query shows a special extract of the data I'm looking at.
Select duration, event_type, start_time, code_range, request_id from MYTABLE where REQUEST_ID = 'abc '.
This translates into the following lines (separate columns by ' / '):
START_TIME/REQUEST_ID/EVENT_TYPE/CODE_RANGE/DURATION
2010-11-12 01:42:04.0/abc/Junk/publicEntryPoint/2,003
2010-11-12 01:42:04.0/abc/Junk/webServiceCall/947
2010-11-12 01:42:04.0/abc/Junk/webServiceCall/969
Another similar request with REQUEST_ID = 'def' means:
START_TIME/REQUEST_ID/EVENT_TYPE/CODE_RANGE/DURATION
2010-11-12 00:22:13.0/def/junk/webServiceCall/788
2010-11-12 00:22:13.0/def/junk/webServiceCall/1,128
2010-11-12 00:22:13.0/def/junk/publicEntryPoint/2,003
What follows is an excerpt simplified query I have a problem with:
Select value start_time request_id event_type, code_range, duration, case code_range
When "publicEntryPoint" then length * 2 - sum (duration) over (partition by request_id)
of another-1
end inner_duration from MYTABLE where EVENT_TYPE = 'spam' and trunc (START_TIME) = to_date('2010-11-12','yyyy-mm-dd')
and rownum < 1000;
Notice the couple of unconventional functions used here, the ' case/when' and 'sum() over (partition).
This property returns a bunch of lines (count: 999), but here are the two with the particular REQUEST_ID values:
START_TIME/REQUEST_ID/EVENT_TYPE/CODE_RANGE/DURATION/INNER_DURATION
2010-11-12 01:42:04.0/abc/junk/publicEntryPoint/2,003/2,003
2010-11-12 00:22:13.0/def/junk/publicEntryPoint/2,003/87
The second line is correct. The first line has an unexpected value of INNER_DURATION of 2003. It should be 87 as the second row. I don't understand why this is happening.
I think that 'and rownum '.<1000" must="" be="" the="" problem.="" it="" must="" be="" excluding="" some="" of="" the="" rows="" needed="" for="" the="" sum.="" the="" analytic="" function="" will="" be="" applied="" after="" this="" condition--see="" the="" sql="">1000">
Analytical functions are the last set of operations performed in a query, except for the
final ORDER BY clause. Every joint and every WHERE, GROUP BY and HAVING clauses are
completed before the analytical functions are processed
Have you tried the query without this condition?
Kind regards
Bob
Tags: Database
Similar Questions
-
Subselect with clause with and nvl() with case when as 2nd argument does not work
I get an error for this one
Select)
with x
(select 1 of the double)
Select
NVL (x.a, cases where x.a is null then fine otherwise 3 2)
the double)
of the double
Error is:
ORA-00904: 'X '. "' A ': invalid identifier
... related to the use of x.a in an expression box as the 2nd argument of nvl (...)
Rgds,
Frank
Hello
Maybe like this?
Select)
with x
(select 1 of the double)
Select
NVL (x.a, case when x.a is null, then Itf_Pkg.Itf_Null_Value ("x.a', 'a null value'") or 3 end)
X)
of the double
-
Problem with case when try to alter the query from siimple
Hello PL/SQL gurus and Experts.
I'm stuck with a question (can be simple), but not gettings all headsway.
value returns is as - 1.46select 365/day_num_yr Anul_Fact from Date where date_dt = trunc(sysdate -1)
need to write it in the form of case (I have to multiply it to some other outer query), I want to store variable ina and then use the same in an outside -.
but when use the following syntax, then it always returns 0 and not the same output returned by the query above without the scabbard.
Help kindly, I appericate your time and effort in advance.select (case when date_dt =trunc(sysdate -1) then 365/day_num_yr else 0 END) Anul_Fact
user555994 wrote:
Problem is that I do not get the output as 1.46, even the output is coming like the 0 only if using the query - nextselect /*date_dt, sysdate - 1 prev_dt, trunc(sysdate - 1) trunc_prev_dt,*/ case when date_dt = trunc(sysdate -1) then 365/day_num_yr else 0 end num_day from date_dim;
Completely, which seems to be a question of DATA. Have you checked if the table contains data for DATE_DT = SYSDATE - 1? Can you check if the data stored do not have hours and Minutes stored?
Although I have provided examples of data, which is the same as the data in my main table and once I used the previous solution you provided and then also gives the result as same as those mentioned by you.
I think it's something like -
select date_dt, sysdate - 1 prev_dt, trunc(sysdate - 1) trunc_prev_dt, case when date_dt = trunc(sysdate -1) then 366/day_num_yr where day_num_yr=(select day_num_yr from date_dim where date_dt = trunc(sysdate -1)) else 0 end num_day from date_dim;
Once we get the day_num_yr then he deviding by 366/day_num_yr :(
but he does not like throwing an error ORA-95 - missing keywordYes, it does not work
-case when date_dt = trunc (sysdate-1) then 366/day_num_yr where day_num_yr = (select day_num_yr from the date_dim where date_dt = trunc (sysdate-1))
due to a syntax of alien.
I don't think that you really need. I already said, with the data in your Table, you will be having only * 1 * record with a Non - zero value. Thus, simply apply a filter to extract the corresponding record SYSDATE - 1 and you should get an output which is Non-zero. If you apply a where predicate, then would not need you a CASE statement. You can directly use something like below:select date_dt, sysdate - 1 prev_dt, trunc(sysdate - 1) trunc_prev_dt, 365 / day_num_yr num_day from t4 where date_dt = trunc(sysdate - 1);
Published by: Jen K, September 7, 2012 16:00
-
Optimize SQL with case-when-other
Hello
try to categorize DateValue into 3 groups
1. effective: current month
2. for a YEAR: between January and last month of the current year
3. for a YEAR: between January and last month of the last year
I have a feeling that my SQL could be much shorter and faster. I would be grateful for professional advice...
-case when TO_NUMBER ((TO_CHAR (DOCUMENT_TIMESTAMP, 'YYYY') |)) To_char (DOCUMENT_TIMESTAMP, 'MM'))) = TO_NUMBER (TO_CHAR (sysdate, 'YYYY') |) To_char (sysdate, 'MM'))
can 'real '.
-FOR A YEAR
When TO_NUMBER ((TO_CHAR (DOCUMENT_TIMESTAMP, 'YYYY') |)) To_char (DOCUMENT_TIMESTAMP, 'MM'))) between TO_NUMBER (TO_CHAR (sysdate, 'YYYY') |) (' 01') and TO_NUMBER (TO_CHAR (sysdate, 'YYYY') |) To_char (sysdate, 'MM'))-1
then "CDA".
-PYTD
When TO_NUMBER ((TO_CHAR (DOCUMENT_TIMESTAMP, 'YYYY') |)) To_char (DOCUMENT_TIMESTAMP, 'MM'))) between TO_NUMBER (TO_CHAR(sysdate, 'YYYY')-1). ' 01' and TO_NUMBER (TO_CHAR(sysdate, 'YYYY')-1 |) To_char (sysdate, 'MM'))-1
then "PYTD".
else "Others" end up as ABCHello
I find trunc to be more readable:
SQL> WITH DATA AS ( 2 SELECT SYSDATE d FROM dual UNION ALL 3 SELECT add_months(SYSDATE, -12) FROM dual UNION ALL 4 SELECT DATE '2009-01-01' FROM dual 5 ) 6 SELECT to_char(d, 'dd-mon-yyyy') "Date", 7 CASE 8 WHEN trunc(d, 'month') = trunc(SYSDATE, 'month') THEN 9 'Actual' 10 WHEN trunc(d, 'year') = trunc(SYSDATE, 'year') AND d < sysdate THEN 11 'YTD' 12 WHEN trunc(d, 'year') = add_months(trunc(SYSDATE, 'year'), -12) THEN 13 'PYTD' 14 END "Case" 15 FROM DATA 16 ; Date Case ----------------- ------ 10-jun-2009 Actual 10-jun-2008 PYTD 01-jan-2009 YTD
Kind regards
--
VincentPublished by: user11163377 on June 10, 2009 02:12 - corrected the CDA column
-
Need help with CASE When statement in a Where Clause
So I have a SQL (simplified for this forum)
Select t1.*
from table1, table2 t2 t1
where t1.field1 = t2.field1
and when t1.field2 is null then trunc (sysdate) < = trunc (t1.date1 + 17)
of another trunc (sydate) > = end of trunc (t2.date2 + t2.date3)
I end up getting an error ORA-00905: lack of keyword
I'm sure that I just got something here involved.You can not make the comparison within the statement underlying case like this. Assuming you have appropriate data types, something like this should work
Select t1.* from table1 t1, table2 t2 where t1.field1 = t2.field1 and ((t1.field2 is null and trunc(sysdate) <= trunc(t1.date1 + 17)) or trunc(sydate) > = trunc(t2.date2 + t2.date3))
John
-
Helps with the sum on partition
Hi all
This is my sample data:
create table general( general_id number, general_type nvarchar2(10), start_year number, end_year number, fy number, fy_value number ); insert into general(general_id, general_type, start_year, end_year, fy, fy_value) values (1, 'data 1', 2009, 2013, 2010, 10); insert into general(general_id, general_type, start_year, end_year, fy, fy_value) values (1, 'data 1', 2009, 2013, 2013, 20); insert into general(general_id, general_type, start_year, end_year, fy, fy_value) values (2, 'data 2', 2010, 2014, 2010, 5); insert into general(general_id, general_type, start_year, end_year, fy, fy_value) values (2, 'data 2', 2010, 2014, 2013, 15); SELECT general_id, general_type, fy, sum(fy_value) over (partition by general_id, general_type order by fy) sum_fy_value FROM general
My results:
GENERAL_ID GENERAL_TYPE FY SUM_FY_VALUE 1 data 1 2010 10 1 data 1 2013 30 2 data 2 2010 5 2 data 2 2013 20
How can I complete the sum of the missing years (with leading zeros), from my year start and end?
Example of final results:
GENERAL_ID GENERAL_TYPE FY SUM_FY_VALUE 1 data 1 2009 0 1 data 1 2010 10 1 data 1 2011 10 1 data 1 2012 10 1 data 1 2013 30 2 data 2 2010 5 2 data 2 2011 5 2 data 2 2012 5 2 data 2 2013 20 2 data 2 2014 20
Oracle Database 11g - 11.2.0.4.0
Thanks in advance.
SQL> with t 2 as 3 ( 4 select general_id 5 , general_type 6 , start_year + (level-1) fy 7 from ( 8 select distinct general_id 9 , general_type 10 , start_year 11 , end_year 12 from general 13 ) 14 connect 15 by level <= end_year - start_year + 1 16 and prior general_id = general_id 17 and prior dbms_random.value is not null 18 ) 19 select t.general_id 20 , t.general_type 21 , t.fy 22 , sum(nvl(g.fy_value, 0)) over(partition by t.general_id order by t.fy) sum_fy_value 23 from t 24 left join 25 general g 26 on t.general_id = g.general_id 27 and t.fy = g.fy 28 order 29 by general_id 30 , fy; GENERAL_ID GENERAL_TY FY SUM_FY_VALUE ---------- ---------- ---------- ------------ 1 data 1 2009 0 1 data 1 2010 10 1 data 1 2011 10 1 data 1 2012 10 1 data 1 2013 30 2 data 2 2010 5 2 data 2 2011 5 2 data 2 2012 5 2 data 2 2013 20 2 data 2 2014 20 10 rows selected.
Note: I must say that it is one of these well posed the question, which we do not often here. I appreciate you providing sample data and expected outcomes in a well-formatted way and also provides the oracle version 4-digit.
-
Can I change the icon of the cursor when hover over one active link with another?
Can I change the icon of the cursor when hover over one active link with another?
Muse does not natively support, but all you need to do to make it work is on your page, add properties in the head content:
a {
cursor: value;
}
Where "value" is the cursor you want for example for a cross-shaped cursor...
a {
cursor: crosshair;
}
-
Helps with the instruction WHEN SUM
I have the following code which works without a problem. However, I need to add an extra parameter. I need to SUM when the name of the month is > 0 and less than 37. How can I add the > option 0?
Thank you!
, sum (case when month_name < 37 then qty_used 0 otherwise end) M_0Hello
847497 wrote:
I have the following code which works without a problem. However, I need to add an extra parameter. I need to SUM when the name of the month is > 0 and less than 37. How can I add the > option 0?Thank you!
sum (case when month_name< 37="" then="" qty_used="" else="" 0="" end)="">
Conditions in a CASE expression can be compound conditions, linked by AND or or, as the conditions in a WHERE clause.
SUM ( CASE WHEN month_name > 0 AND month_name < 37 THEN qty_used ELSE 0 END ) AS m_0
-
error when using ' select case-sensitive when sum() group by»
SELECT REGION_CODE
REGION_DESC
CASE WHEN END OF SUM (UP_SMS_TIMES) BETWEEN T2.SMS_MIN AND T2.SMS_MAX THEN T2.SMS_LVL_CODE
OF PMID. TB_MID_PAR_EXT_USER_MON T1, EDCP. TB_CDE_SMS_LVL T2
WHERE DEAL_DATE = '200811'
REGION_CODE GROUP, REGION_DESC
{color: #ff0000} error: ORA-00979: not a GROUP BY expression
{color} {color: #000000} How can I fix the error, thanks {color}Hello
Try this query:
SELECT t1.region_code,
T1.region_desc,
MAX (t2.sms_lvl_code) AS sms_lvl
FROM (SELECT region_code,
region_desc,
SUM (up_sms_times) up_sms_times
OF tb_mid_par_ext_user_mon
WHERE deal_date = '200812'
AND up_sms_times > 0
Region_code GROUP,
region_desc T1),
tb_cde_sms_lvl t2
WHERE the t1.up_sms_times BETWEEN t2.sms_min AND t2.sms_max
T1.region_code GROUP, t1.region_descKind regards
Shandy Hidayat
-
SUM on &; Partition BY... Try to get the correct total run.
running: Oracle XE 11
Hi all, I am using the analytical function of PARTITION BY to get my total race for a report. (in this case the bank balance)
SUM (bank_stmts.amount) OVER (PARTITION BY bank_stmts.account_ID ORDER BY bank_stmts.tx_date, bank_stmts.id)
I add a balance initial in the table at the beginning of the year, and everything works fine when I select on the recordings of the whole years...
However, I need to interview a subset of the report, i.e. one month, or a selection of documents, rather than year-round. But I still want to see the total calculated for the whole year on the report, not a total operating for the subset of records. I'm not sure how to do that because when I select a subset, it totals only the subset...
I see that there are a number of clauses on the analytical function, especially BETWEEN the LINES or RANGE, but my assumption is that these still only works on surveyed lines and not any of the table...
My way of thinking for the moment, is that patients have to calculate and enter the total in the table when the row is inserted, probably via a trigger. However, I didn't keep far from...
Kind regards
Richard
SQL > with t as)
2. Select ename,
3 job,
4 hiredate,
5 sum (sal) over (partition by deptno arrested by hiredate) running_total_sal
6 of PEM
7 )
8 select
9 t
10 order by hiredate
11.HIREDATE RUNNING_TOTAL_SAL EMPLOYMENT ENAME
------ --------- --------- -----------------
SMITH, CLERK DECEMBER 17, 80 800
ALLEN SALESMAN FEBRUARY 20 81 1600
WARD 22 FEBRUARY SALESMAN 81 2850
MANAGER OF JONES 2 APRIL 81 3775
BLAKE MANAGER MAY 1, 81 5700
CLARK MANAGER JUNE 9, 81 2450
SELLER OF 7200 08 - SEP - 81 TURNER
MARTIN SELLER 28-SEP-81 8450
PRESIDENT KING NOVEMBER 17 81-7450
JAMES CLERK 9400 3 DECEMBER 81
DECEMBER 3, 81 FORD ANALYST 6775HIREDATE RUNNING_TOTAL_SAL EMPLOYMENT ENAME
------ --------- --------- -----------------
MILLER COMMITTED JANUARY 23, 82 8750
SCOTT, ANALYST APRIL 19 87 9775
ADAMS, CLERK MAY 23, 87 1087514 selected lines.
SQL > with t as)
2. Select ename,
3 job,
4 hiredate,
5 sum (sal) over (partition by deptno arrested by hiredate) running_total_sal
6 of PEM
7 )
8 select
9 t
10 where hiredate > = date ' 1981-01-01'
11 and hiredate< date=""> >
12 order by hiredate
13.HIREDATE RUNNING_TOTAL_SAL EMPLOYMENT ENAME
------ --------- --------- -----------------
ALLEN SALESMAN FEBRUARY 20 81 1600
WARD 22 FEBRUARY SALESMAN 81 2850
MANAGER OF JONES 2 APRIL 81 3775
BLAKE MANAGER MAY 1, 81 5700
CLARK MANAGER JUNE 9, 81 2450SQL >
SY.
-
Interview with incrementing field which resets on certain conditions?
I have this query which gives a history of the units that is painted in our production process and flags when there is a change in color.
That gives me results that look like this.select LINE_DESCR, PAINT_TIME, COLOR, lag(COLOR) over (partition by LINE_DESCR order by PAINT_TIME) PREV_COLOR, case when COLOR != lag(COLOR) OVER (PARTITION by LINE_DESCR ORDER BY PAINT_TIME) then 1 else 0 end COLOR_CHANGE from UNIT_PAINTINGS up, UNIT_PAINT_LINES upl, UNIT_INFO ui where up.LINE_ID = upl.ID and up.UNIT_ID = ui.ID and PAINT_TIME between sysdate - 1 and sysdate
I want to add a count of the number of units between color changes, which will be increments when COLOR_CHANGE = 0 and back to 1 when COLOR_CHANGE = 1, like this:LINE_DESCR PAINT_TIME COLOR PREV_COLOR COLOR_CHANGE IPP 1 4/9/2013 16:06:53 A82 A52 1 IPP 1 4/9/2013 16:08:46 354 A82 1 IPP 1 4/9/2013 16:10:21 475 354 1 IPP 1 4/9/2013 16:12:05 475 475 0 IPP 1 4/9/2013 16:15:25 475 475 0 IPP 1 4/9/2013 16:17:01 475 475 0 IPP 1 4/9/2013 16:18:55 475 475 0 IPP 1 4/9/2013 16:20:44 668 475 1 IPP 1 4/9/2013 16:22:32 475 668 1 IPP 1 4/9/2013 16:24:26 475 475 0
Suggestions on how to do this better?LINE_DESCR PAINT_TIME COLOR PREV_COLOR COLOR_CHANGE PAINTED_UNITS IPP 1 4/9/2013 16:06:53 A82 A52 1 1 IPP 1 4/9/2013 16:08:46 354 A82 1 1 IPP 1 4/9/2013 16:10:21 475 354 1 1 IPP 1 4/9/2013 16:12:05 475 475 0 2 IPP 1 4/9/2013 16:15:25 475 475 0 3 IPP 1 4/9/2013 16:17:01 475 475 0 4 IPP 1 4/9/2013 16:18:55 475 475 0 5 IPP 1 4/9/2013 16:20:44 668 475 1 1 IPP 1 4/9/2013 16:22:32 475 668 1 1 IPP 1 4/9/2013 16:24:26 475 475 0 2
Thank you
FaridaHi, Farida,
Maybe:
WITH got_grp_num AS ( select LINE_DESCR, PAINT_TIME, COLOR , lag( COLOR) over ( partition by LINE_DESCR order by PAINT_TIME ) AS PREV_COLOR , case when COLOR != lag (COLOR) OVER ( PARTITION by LINE_DESCR ORDER BY PAINT_TIME ) then 1 else 0 end AS COLOR_CHANGE , ROW_NUMBER () OVER ( PARTITION BY line_descr ORDER BY paint_time ) - ROW_NUMBER () OVER ( PARTITION BY line_descr , color ORDER BY paint_time ) AS grp_num from UNIT_PAINTINGS up , UNIT_PAINT_LINES upl , UNIT_INFO ui where up.LINE_ID = upl.ID and up.UNIT_ID = ui.ID and PAINT_TIME between sysdate - 1 and sysdate ) SELECT line_descr, paint_time, color , prev_color, color_change , ROW_NUMBER () OVER ( PARTITION BY line_descr , color , grp_num ORDER BY paint_time ) AS painted_units FROM got_grp_num ;
If you would care to post CREATE TABLE and INSERT statements for your sample data, and then I could test this.
Looks like the painted_units can be generated by the analytical ROW_NUMBER function. Obviously, we want to ORDER BY paint_tme, but what can we PARTITION BY? Line_desc? Yes, we are a numbrs o setting separately for each line_desc, but we may need several sets of ROW_NUMBERs for the same lin_desc. Can you color and PARTITION BY line_descr? Yes, a set of numbers will apply only to a particular combination of line_descr and color, but what happens if the stats of color as a thing, then changes and modifications to the original color? We need a whole separate ROW_NUMBERs for each of these groups. That's exactly what grp_num is. (Notice the got_grp_num of the subquery is just your request of moose, more than an additional column.) The main request is noting except drifting painted units. We have need of a subquery, because the analytical functions that derive from painted_units depends on the grp_num and grp_num is itself the result of an analytic function and a function anlaytic cannot be dependent on another calculated the same subsidiary query.
See for an explanation of the technique Difference sets used to calculate the grp_num, {message: id = 9953384} and/or {message identifier: = 9957164}
-
Hello
I'm doing something that I think is quite a common request, but after scratching my head and browsing the web I am still not close to a solution.
I am running:
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
I'm looking to summarize a set of values, taking into account the two parent grouping and start and end dates.
I use for the parent of grouping:
+ Sum ([value]) over (Partition by order [Parent] [parent], [Child]) +.
I was hoping to expand that AMOUNT to manage also the start and end dates, so the end result would contain a sum of the values for each different period of time.
For example, using the data below I try to sum up the prices of the components of a car over time:
line, product, component, rate, start date, end date
1, car, chassis, 180, 01/01/2000, 31/12/2009
2, car, chassis, 200, 01/01/2010, 01/01/2050
3, car, engine, 100, 01/01/2000, 01/01/2050
Notice that there is a price for "Chassis" of item change, so the output, I'm looking for is:
line, product, component, rate, start date, end date, sum
1, car, chassis, 180, 280 01/01/2000, 31/12/2009,
2, car, engine, 100, 280 01/01/2000, 31/12/2009,
3, car, chassis, 200, 01/01/2010, 01/01/2050, 300
4, car, engine, 100, 01/01/2010, 01/01/2050, 300
But in reality, everything I need is:
Row, product, start date, end date, sum
1, car, 01/01/2000, 31/12/2009, 280
2, cars, 01/01/2010, 01/01/2050, 300
Preference the query would be a view instead of a stored procedure, and he must be able to manage many 'products', 'components' and start and end dates.
All help most appreciated and if need more info, please let me know.
Thank you
JulianHi, Julian,.
I think I understand.
You want to use the lump SUM, not the analytical SUM. The analytical function you would give a total for the entire product, but would keep the individual lines for each component. But you don't want individual lines for each component; you want to just one line for each product and the period. The tricky thing with this problem is to set a period. In the following query, a new period for a given product begins when there is a start_date or an end_date for this product, which is calculated in the sub_query called periods.The following subquery, active_ratews, see what rate applied during this period, seeing the lines in product_rates overlap with the lines in periods. Two overlap if everyone will start before the other ends. If it's not obvious to you (and it is of course obvious to me when I heard it), then look at it this way: two ranges are not overlapping if (and only if) one end before another begins.
The result of the ios active_rates close enough of what you posted as intermediate results. The main request that added all the lines for the same product and timely.
WITH period_start_points AS ( SELECT product , start_date FROM product_rates UNION SELECT product , end_date + 1 AS start_date FROM product_rates ) , periods AS ( SELECT product , start_date , LEAD (start_date) OVER ( PARTITION BY product ORDER BY start_date ) AS end_date FROM period_start_points ) , active_rates AS ( SELECT p.product , p.start_date , p.end_date - 1 AS end_date , r.component , r.rate FROM periods p JOIN product_rates r ON p.product = r.product AND p.start_date <= r.end_date AND r.start_date < p.end_date ) SELECT ROW_NUMBER () OVER ( ORDER BY product , start_date ) AS row_n , product, start_date, end_date , SUM (rate) AS total_rate FROM active_rates GROUP BY product, start_date, end_date ORDER BY product, start_date ;
Viguierkevin wrote: in addition, a quick query to improve my ads - how indent without doing ittallic of text, and how to code a different font?
This site normally does not display multiple spaces in a row.
Whenever you post the text formatted (for example, the results of the query) on this site, type the 6 characters:\
(small letters only, inside curly brackets) before and after each section of formatted text, to preserve spacing. Everything between the \
tags appear in a police fixed-width.
Published by: Frank Kulash, January 4, 2012 14:09
Added explanation. -
Error number invalid when using case when
I have a table called NATIONAL_RARE_ECOSYSTEMS that contains 1 column called TEST_COLUMN (data type: varchar2):
TEST_COLUMN
rare ecosystem
rare
0
0
(null)
(null)
what I want is a query that will add a column called NRE_SCORE that will give each instance of line a score of 0 if it is null.
If it is 0, then the score should be 0.
If the line contains any text, partition should be 1
I wrote the request:
SELECT
(CASE WHEN test_column is null THEN 0)
WHEN test_column = 0 THEN 0
WHEN test_column > 0, 1
END) AS NRE_SCORE
OF NATIONAL_RARE_ECOSYSTEMS;
I get the error message:
ORA-01722: invalid number
01722 00000 - "invalid number."
I think it is because on the 2nd and 3rd line, trying to perform arithmetic operations on a column which is varchar2 which I know that I can't do.
How can I write a query that says: If the line contains text, then gives the score of 1?
I'm using oracle 11g.Hello
993451 wrote:
I have a table called NATIONAL_RARE_ECOSYSTEMS that contains 1 column called TEST_COLUMN (data type: varchar2):TEST_COLUMN
rare ecosystem
rare
0
0
(null)
(null)what I want is a query that will add a column called NRE_SCORE that will give each instance of line a score of 0 if it is null.
If it is 0, then the score should be 0.
If the line contains any text, partition should be 1Any text other than '0', you mean. I guess that doesn't matter if this text is all the numbers, like '9876 'or something with no numbers, as 'rare'.
I wrote the request:
SELECT
(CASE WHEN test_column is null THEN 0)
WHEN test_column = 0 THEN 0
WHEN test_column > 0 THEN 1
END) AS NRE_SCORE
OF NATIONAL_RARE_ECOSYSTEMS;I get the error message:
ORA-01722: invalid number
01722 00000 - "invalid number."I think it is because on the 2nd and 3rd line, trying to perform arithmetic operations on a column which is varchar2 which I know that I can't do.
You are not actually doing arithmetic, but you compare your VARCHAR2 column, so he tries to convert the string to a NUMBER, and that's why you get the error ORA-01722.
>How can I write a query that says: If the line contains text, then gives the score of 1?
I'm using oracle 11g.
Here's one way:
SELECT CASE WHEN NVL (test_column, '0') = '0' THEN 0 ELSE 1 END AS nre_score , ... -- you must want other columns, too FROM national_rare_ecosystems ;
Since you are not really care on the numerical value, do not use numbers anywhere; stick with VARCHAR2s, for example '0'.
I hope that answers your question.
If not, post a small example data (CREATE TABLE and only relevant columns, INSERT statements) and also publish outcomes from these data.
Point where the above query was to get erroneous results, and explain, using specific examples, how you get these results of the sample data in these palces.
See the FAQ forum {message identifier: = 9360002} -
Hello people.
FIELDS IN TABLE OF PHONE CALLS: EMP_ID, TELNO, COST, TYPE
TYPE can be GIVEN or VOICE
1 EMP_ID has more than 1 TELNO
I need a report with the following columns:
EMP_ID, TELNO, VOICE_COST, DATA_COST
I need something like:
Thank you in advance.SELECT EMP_ID , TELNO, SUM(COST), SUM(CASE COST WHEN TYPE = DATE THEN ...... END) AS VOICE, SUM(CASE COST WHEN TYPE = VOICE ...... END) AS DATA FROM PHONECALLS GROUP BY EMP_ID, TELNO ORDER BY EMP_ID ASC;
Something like that?
SELECT EMP_ID , TELNO, SUM(COST), SUM(CASE TYPE WHEN 'DATE' THEN COST END) AS VOICE, SUM(CASE TYPE WHEN 'VOICE' THEN COST END) AS DATA FROM PHONECALLS GROUP BY EMP_ID, TELNO ORDER BY EMP_ID ASC;
Or the alternative way of use CASES:
SELECT EMP_ID , TELNO, SUM(COST), SUM(CASE WHEN TYPE = 'DATE' THEN COST END) AS VOICE, SUM(CASE WHEN TYPE = 'VOICE' THEN COST END) AS DATA FROM PHONECALLS GROUP BY EMP_ID, TELNO ORDER BY EMP_ID ASC;
The first use of the CASE is simple - the other can have as expressions complex enough ;-)
-
Hello
I get incorrect results when I run my SQL on Oracle 10.2.0.4 prod database.
When I run the same SQL on Oracle 11.2.0.1 prod database, I get the results I expect.
See the PATH_TO_EMP_ROOT column in 10g (all are null, why?)
Here's the SQLs and respective results on Oracle 10.2.0.4 prod database:
Exact same SQL running on * 11.2.0.1 Oracle database * as a result of results (than I expected on 10.2 as well):create table TEST_WITH_EMP_TABLE ( EMP_ID NUMBER(5) NOT NULL, EMP_NAME VARCHAR2(100) NOT NULL, MGR_EMP_ID NUMBER(5), CONSTRAINT TEST_WITH_EMP_TABLE_PK PRIMARY KEY (EMP_ID) USING INDEX, CONSTRAINT TEST_WITH_EMP_TABLE_FK1 FOREIGN KEY (MGR_EMP_ID) REFERENCES TEST_WITH_EMP_TABLE(EMP_ID) ON DELETE CASCADE ); INSERT INTO TEST_WITH_EMP_TABLE VALUES (10, 'Emp1', null); INSERT INTO TEST_WITH_EMP_TABLE VALUES (20, 'Emp2', 10); INSERT INTO TEST_WITH_EMP_TABLE VALUES (30, 'Emp3', 20); INSERT INTO TEST_WITH_EMP_TABLE VALUES (40, 'Emp4', 30); INSERT INTO TEST_WITH_EMP_TABLE VALUES (50, 'Emp5', 10); INSERT INTO TEST_WITH_EMP_TABLE VALUES (60, 'Emp6', 50); INSERT INTO TEST_WITH_EMP_TABLE VALUES (70, 'Emp7', 10); INSERT INTO TEST_WITH_EMP_TABLE VALUES (80, 'Emp8', null); commit; select level as EMP_LEVEL, sys_connect_by_path(EMP_ID, '/') as PATH_TO_EMP_ROOT, COUNT(*) OVER (PARTITION BY level, MGR_EMP_ID) as EMPS_COUNT, EMP_ID, EMP_NAME, MGR_EMP_ID from TEST_WITH_EMP_TABLE START WITH MGR_EMP_ID IS NULL CONNECT BY NOCYCLE PRIOR EMP_ID = MGR_EMP_ID ORDER BY EMP_LEVEL, MGR_EMP_ID; EMP_LEVEL PATH_TO_EMP_ROOT EMPS_COUNT EMP_ID EMP_NAME MGR_EMP_ID --------- ---------------- ---------- ------ -------- ----------- 1 (null) 2 10 Emp1 (null) 1 (null) 2 80 Emp8 (null) 2 (null) 3 20 Emp2 10 2 (null) 3 50 Emp5 10 2 (null) 3 70 Emp7 10 3 (null) 1 30 Emp3 20 3 (null) 1 60 Emp6 50 4 (null) 1 40 Emp4 30
Y at - it a bug known RDBMS? Any change that I can do to get this working on 10.2, SQL database as well?EMP_LEVEL PATH_TO_EMP_ROOT EMPS_COUNT EMP_ID EMP_NAME MGR_EMP_ID --------- ---------------- ---------- ------ -------- ----------- 1 /10 2 10 Emp1 (null) 1 /80 2 80 Emp8 (null) 2 /10/20 3 20 Emp2 10 2 /10/50 3 50 Emp5 10 2 /10/70 3 70 Emp7 10 3 /10/20/30 1 30 Emp3 20 3 /10/50/60 1 60 Emp6 50 4 /10/20/30/40 1 40 Emp4 30
The other strange thing is that if I remove the
the select part of SQL on 10.2.0.4 DB column, theCOUNT(*) OVER (PARTITION BY level, MGR_EMP_ID) as EMPS_COUNT
I get now is correct even on the 10.2 database.PATH_TO_EMP_ROOT
Kind regards
Vivek.select level as EMP_LEVEL, sys_connect_by_path(emp_id, '/') as path_to_emp_root, --COUNT(*) OVER (PARTITION BY MGR_EMP_ID) as EMPS_COUNT, EMPS_COUNT, emp_id, emp_name, mgr_emp_id from (select emp_id, emp_name, mgr_emp_id, count(*) over (partition by mgr_emp_id) as emps_count from TEST_WITH_EMP_TABLE) start with mgr_emp_id is null connect by nocycle prior emp_id=mgr_emp_id ORDER BY EMP_LEVEL, MGR_EMP_ID;
Maybe you are looking for
-
UJ-840 CDROM in a Qosmio F20 years does not correctly read the media
Hi people,I m getting desperate now! Have a dissitation I need to access with a cdrom (UJ - 840 years) on a Qosmio F20 running Windows Vista Ultimate.A message says that it is not connected, even if it will read CDs. Can someone help please. When I i
-
EliteBook 8540w: RJ-11 Port
Hey, can I connect internet without the router via the RJ-11 port... Tell me how to set up he...
-
Control data DATAKOM DKM 409 RS485 modbus output
Hello world My project is to control a furnace and im using DATAKOM DKM 409 with rs485 modbus output. in this project, I want to monitor data using labview. reason to do this, I use a RS 485 to RS 232 converter but when I connect them to each other
-
Which is faster a bit manipulation to the table or image using the vision
I have to perform an operation on an image. It involves the calculation of the new locations for the pixels for each pixel of the image. Which is the fastest way to do it. Manipulate the pixels as elements of the array for loops, or manipulate the
-
Hello from blackBerry Smartphones
Hello, in spite of having a "BOLD" for a year now I'm new here. Recently changed handset that the original stopped battery charge. And now I have problems of vaious with applications. (1) can't download windows live messenger. simply no button to do.