UNION ALL destroyed performance
Strangely, we have 2 queries, which, when they run independently, running fast enough (2 seconds on the one hand, instantaneous to the other), but when they are concatenated into a UNION ALL query without the ORDER BY clause, it takes 45 seconds for him to run.We tried to push the SQL code in a WITH clause and some other rewrites of the subquery, but no performance boost. Anyone seen this before?
version 10.1.0.4
-= Chuck
just a thought... I didn't really study plans explain it... (I find these very difficult to read, you do not have these SQL * Plus, you did?)
Tom Kyte mentioned somewhere (I find the thread later) you can use ROWNUM in two UNION ALL queries to "refine" the query. You might want to try it.
Because of the ROWNUM materialize you each request separately before combining the results.
Tags: Database
Similar Questions
-
Please help me with the Alternative of queries to replace the UNION ALL for two queries
Hi all
I have the query to retrieve assets employees salary count and in so far as below:
Select ename, emp_no, sum (sal_till_2010), sum (sal_till_2014) of
(select emp_no, ename, salary as sal_till_2010, 0 as sal_till_2014 of employee e1
where effective_date < = 1 January 2010 ' and not exists (select 1 from e2 employee_deletion where e2.emp_no = e1.emp_no and e2.deletion_date < = January 1, 2010 "")
UNION ALL
Select ename, emp_no, 0 as sal_till_2010, salary as employee e1 sal_till_2014 - here is a dummy 0 salary until 2010 for the union of all the
where effective_date < = 1 January 2014 "and not exists (select 1 from e2 employee_deletion where e2.emp_no = e1.emp_no and e2.deletion_date < = 1 January 2014") "
Group of emp_no, ename;
In this query, I get the total salary until 2010 and until 2014 in the employee table, dates are dynamically passed to the procedure, and this can change.
But assume the date above and let me know the alternative of queries to improve performance because I use Union ALL and read the same table twice in the above query.
Advice me with request to read the table once to fetch the same data as the above query.
Thanks in advance.
Hello
Thanks for the display of the data of the sample; It's very useful!
I think OP wants something like this:
WITH cutoff_dates AS
(
SELECT TO_DATE (January 1, 2010 ', ' DD/MM/YYYY') AS cutoff_date, 2010 UNDER the label OF dual UNION ALL
SELECT TO_DATE (1 January 2014 ', "DD/MM/YYYY"), double 2014
)
SELECT e.emp_no, e.ename
, NVL (SUM (CASE WHEN c.label = 2010 THEN e.salary END), 0) AS sal_till_2010
, NVL (SUM (CASE WHEN c.label = 2014 THEN e.salary END), 0) AS sal_till_2014
E employee
JOIN cutoff_dates c ON e.effective_date<=>=>
WHERE DOES NOT EXIST)
SELECT 1
Of employee_deletion ed
WHERE ed.emp_no = e.emp_no
AND ed.deletion_date<=>=>
)
E.emp_no GROUP, e.ename
ORDER BY e.emp_no
;
Output of your sample data:
EMP_NO ENAME SAL_TILL_2010 SAL_TILL_2014
---------- ------ ------------- -------------
1 Mickey 450 0
2 Donald 750 0
-
Hello
Oracle 9i performance Guide:
' Concatenation is useful for statements with different conditions, combined with a clause or.
"If a query contains a WHERE clause with multiple conditions combined with GOLD operators, then the optimizer into a compound equivalent query that uses the UNION ALL operator set, if this makes the query to run more efficiently"
Can someone tell me when the concatenation is better than the union and vice versa?
-
My UNION ALL is not enough work - help!
Hi gurus.
I hope one of you fine pro can sort this for me...
I have a script which is currently if there is an employee number to double but NOT if there is a double number of NOR - what code should I include?
Thank you very much...SELECT DISTINCT per.person_id, per.business_group_id, per.last_name, per.start_date, per.date_of_birth, per.email_address, LPAD(per.employee_number,8,'0') employee_number, per.first_name, per.marital_status, per.middle_names, per.nationality, per.national_identifier, per.sex, per.title, padd.address_id, padd.primary_flag, padd.address_line1, padd.address_line2, padd.address_line3, padd.town_or_city, padd.postal_code, padd.telephone_number_1, paas.assignment_id, paas.assignment_number, paas.object_version_number, paas.effective_start_date, paas.effective_end_date, paas.job_id, paas.position_id, paas.location_id, paas.organization_id, paas.assignment_type, paas.supervisor_id, paas.default_code_comb_id, paas.set_of_books_id, paas.period_of_service_id FROM per_all_people_f per, per_all_assignments_f paas, per_addresses padd WHERE padd.person_id = per.person_id AND paas.person_id(+) = per.person_id AND TRIM (LEADING '0' FROM per.employee_number) = TRIM (LEADING '0' FROM :p_emp_number) AND per.national_identifier <> :p_ni_number UNION ALL SELECT DISTINCT per.person_id, per.business_group_id, per.last_name, per.start_date, per.date_of_birth, per.email_address, LPAD(per.employee_number,8,'0') employee_number, per.first_name, per.marital_status, per.middle_names, per.nationality, per.national_identifier, per.sex, per.title, padd.address_id, padd.primary_flag, padd.address_line1, padd.address_line2, padd.address_line3, padd.town_or_city, padd.postal_code, padd.telephone_number_1, paas.assignment_id, paas.assignment_number, paas.object_version_number, paas.effective_start_date, paas.effective_end_date, paas.job_id, paas.position_id, paas.location_id, paas.organization_id, paas.assignment_type, paas.supervisor_id, paas.default_code_comb_id, paas.set_of_books_id, paas.period_of_service_id FROM per_all_people_f per, per_all_assignments_f paas, per_addresses padd WHERE padd.person_id = per.person_id AND paas.person_id(+) = per.person_id AND TRIM (LEADING '0' FROM per.employee_number) = TRIM (LEADING '0' FROM :p_emp_number) AND per.national_identifier = :p_ni_number;
StevenHello
JackyWhite wrote:
.. the first section is scheduled to end withAND per.national_identifier <> p_ni_number
but for some reason any of this is not displayed on the screen.
Do you mean it is supposed to be an inequality raise it after per.national_identifier and before p_ni_number ?
This site do not display the operator <>, even inside code tags.
When posting on this site, always use the other inequality operator! =. There is no difference in performance.
>Its mainly because I need to put a RC in the script but could not because of the outer join if it was to be a UNION all operation This is why the half you get first a <> p_ni_number and the second you get an AND per.national_identifier = p_ni_number;...
The restriction OR applies only to outer join conditions. In other words, you can not say
WHERE paas.person_id (+) = per.per.person_id OR pass.fubar (+) = per.fubar
(You can do this by using the notation ANSI; just one of the many reasons we syntax ANSII).
However, you can use OR other conditions; for example:WHERE paas.person_id (+) = per.per.person_id AND ( per.national_identifier != p_ni_number OR per.national_identifier = p_ni_number )
which seems to be what you're trying to do. Moreover, the WHERE clause above is equivalent to
WHERE paas.person_id (+) = per.per.person_id AND per.national_identifier IS NOT NULL AND p_ni_number IS NOT NULL
Whenever you need help, post a few examples of data (CREATE TABLE and INSERT statements), and desired results based on these data to the format.
Simplify as much as possible. For example, your actual query may involve 35 columns, but display only the columns used in the conditions, as well as maybe one more column per table. After that you have a solution for the simplest prioblem, adding that the other columns will be triviial. -
Ask. UNION ALL on two tables of dummy data
I had a bit of SQL that joined a dynamic no cross table with another table of dummy data.
WITH tbl_job_data AS (SELECT 'N' argument1, 'Y' argument2, NULL argument3, 'Y' argument4 FROM DUAL) , tbl_params AS (SELECT 1 col_seq, 'From Project Number' col_prompt, NULL col_data, NULL col_attrib FROM DUAL UNION ALL SELECT 2 col_seq, 'To Project Number' col_prompt, NULL col_data, NULL col_attrib FROM DUAL UNION ALL SELECT 3 col_seq, 'Through Date' col_prompt, NULL col_data, NULL col_attrib FROM DUAL UNION ALL SELECT 4 col_seq, 'Summarize Cost' col_prompt, NULL col_data, NULL col_attrib FROM DUAL) SELECT NULL AS col_seq , NULL AS col_prompt , d.col_data , d.col_attrib FROM tbl_job_data UNPIVOT INCLUDE NULLS (col_attrib FOR col_data IN (argument1 , argument2 , argument3 , argument4) ) d UNION ALL SELECT tbl_params.col_seq , tbl_params.col_prompt , tbl_params.col_data , tbl_params.col_attrib FROM tbl_params; COL_SEQ COL_PROMPT COL_DATA COL_ATTRIB ---------- ------------------- --------- ---------- ARGUMENT1 N ARGUMENT2 Y ARGUMENT3 ARGUMENT4 Y 1 From Project Number 2 To Project Number 3 Through Date 4 Summarize Cost 8 rows selected.
Sorry to be very naïve and ignorant, but is be possible that I can get the output in 4 lines like that, by a union on 2 statements:
COL_SEQ COL_PROMPT COL_DATA COL_ATTRIB ---------- ------------------- --------- ---------- 1 From Project Number ARGUMENT1 N 2 To Project Number ARGUMENT2 Y 3 Through Date ARGUMENT3 4 Summarize Cost ARGUMENT4 Y
I guess not, because the 2 tables don't really have a lot in common with them, but I thought I'd ask.
Thank you
Previously, contributed to these requests by Frank Kulash
https://community.Oracle.com/thread/3810284 et
WITH
tbl_job_data AS
(SELECT "n" argument1, argument2 'Y', NULL argument3, 'Y' argument4)
OF THE DOUBLE
),
tbl_params AS
(SELECT 1 col_seq, number 'of the project"col_prompt, col_data, NULL, NULL col_attrib OF DOUBLE UNION ALL)
SELECT 2 col_seq, col_prompt 'for the project number", NULL, col_data, NULL col_attrib OF DOUBLE UNION ALL
SELECT 3 col_seq, col_prompt 'Date', NULL, col_data, NULL col_attrib OF DOUBLE UNION ALL
SELECT 4 col_seq, col_prompt "summarizes the cost", NULL, col_data, NULL FROM DUAL col_attrib
)
Select y.*, x.*
from (SELECT on col_seq (d.col_data control) row_number()
NULL AS col_prompt
d.col_data
d.col_attrib
OF tbl_job_data
MUST INCLUDE NULL VALUES
(col_attrib
FOR col_data IN (argument1
argument2
argument3
argument4)
) d
) x,.
(SELECT tbl_params.col_seq
tbl_params.col_prompt
tbl_params.col_data
tbl_params.col_attrib
OF tbl_params
) y
where x.col_seq = y.col_seq
COL_SEQ COL_PROMPT COL_DATA COL_ATTRIB COL_SEQ COL_PROMPT COL_DATA COL_ATTRIB 1 Project number - - 1 - ARGUMENT1 N 2 For the project number - - 2 - ARGUMENT2 THERE 3 By Date - - 3 - ARGUMENT3 - 4 Summarize the cost - - 4 - ARGUMENT4 THERE Concerning
Etbin
-
How to filter records in a UNION ALL query
Hi all
I have only one requirement to filter records in a query UNION all. If we do not all matching records to one of the union, all question them.
create table test_1(n1 number,n2 number,n3 number) insert into test_1 values(1,2,3); insert into test_1 values(11,22,33); insert into test_1 values(55,66,77); Case-1 : SELECT N1,N2,N3 FROM TEST_1 WHERE N2=2 UNION ALL SELECT N1,N2,N3 FROM TEST_1 WHERE N3=3 Output is : This is desired output(so we are good) 1,2,3 1,2,3 Case 2 : SELECT N1,N2,N3 FROM TEST_1 WHERE N2=22 UNION ALL SELECT N1,N2,N3 FROM TEST_1 WHERE N3=44 Output : (Here is the problem: If we don't have matching records for anyone union all query we don't want any records) Output is coming : 11,22,33 Out put : No Records (We want this output.)
I hope I have given the clear example of my requirement.
Thank you.
with
test_1 as
(select 1 n1, n2 2, n3 3 of all the double union)
Select 11,22,33 from all the double union
Select double 55,66,77
)
Select the n1, n2, n3
from (select n1, n2, n3
of test_1
where n2 =: n2
Union of all the
Select the n1, n2, n3
of test_1
where = n3: n3
)
where exists (select null from test_1 where n2 =: n2)
and it exists (select null from test_1 where = n3: n3)
Concerning
Etbin
-
An artificial union all:
SQL> SELECT Dummy FROM Dual ORDER BY Dummy; D - X SQL> SELECT Dummy FROM Dual UNION ALL SELECT Dummy FROM Dual ORDER BY Dummy; D - X X SQL> SELECT Dummy FROM Dual UNION ALL SELECT Dummy FROM Dual UNION ALL SELECT Dummy FROM Dual ORDER BY Dummy; D - X X X
It literally changes it:
SQL> SELECT NULL A FROM Dual ORDER BY A; A - SQL> SELECT NULL A FROM Dual UNION ALL SELECT NULL FROM Dual ORDER BY A; A - SQL> SELECT NULL A FROM Dual UNION ALL SELECT NULL FROM Dual UNION ALL SELECT NULL FROM Dual ORDER BY A; SELECT NULL A FROM Dual UNION ALL SELECT NULL FROM Dual UNION ALL SELECT NULL FROM Dual ORDER BY A * ERROR at line 1: ORA-00904: "A": invalid identifier SQL> SELECT NULL A FROM Dual UNION ALL SELECT NULL FROM Dual UNION ALL SELECT NULL FROM Dual ORDER BY 1; A -
Why 3 is the magic number?
My friend, this is what I would call a "bug".
However, my opinion doesn't matter, because I do not work for Oracle
You opened a SR with Oracle?
-
Union all with addistional field
Hello
Maybe this is a stupid question.
I have two tables with 22 columns.
Another table with 23 columns
I want to combine these two tables using union all.
In the first picture, I want back "NA" as the last field.
In the second table, last column is varchar2.
Instead of every column one by one and if I use select * in two queries and add "NA" to one?
I want the union two queries can order and use it with the clause to retrieve values based on conditions somany.
So I have to specify the names of column three times.
I use oracle 10g
Hello Krishna,
Try
select t1.*, 'NA' as
from table1 t1 union select t2.* from table2 t2; concerning
Kay
-
What better union all or create a separate slider
Hi gurus
I wonder if someone can help out me of this union is a good option, or create a separate slider for each union all is a good option. Which is preferable? Thanks in advance
Concerning
Shu
You can use Union all instead of opening cursor much time to record the line and your code in the treatment of the sliders, exceptions.
So it would be better to consider all the data at once and even within a single processing loop.
Kind regards
Prashant da Silva
-
UNION and UNION ALL giving multiple result sets even if INTERSECT does not lines.
Hello
I have a set of two queries. I used the UNION to join the result set. When I used UNION ALL, I get a different result set.
BT when I use INTERSECT, I m not getting all the lines.
SO, which I guess is, as operation INTERSECT isn't Govind all the lines, then the UNION and UNION ALL of the result sets must be simliar.
But I m getting different result sets.
Please guide me.
Thank you.
Hello
UNION returns separate lines; UNION ALL returns all rows that produce queries.
INTERSECT has nothing to do with it. You can have the lines in a single query. For example
Job SELECTION
FROM scott.emp
UNION - ALL THE
SELECT 'FUBAR '.
DOUBLE;
In this example, there is no overlap between the 2 queries (INTERSECT would have 0 rows).
UNION produces 6 lines, because the query at the top of the page produces 5 distinct lines (of 14 total ranks) and the background query 1.
UNION ALL product lines 15: 14 of the request from top and 1 of the request from the lower part.
I hope that answers your question.
If not, post a test script (if necessary) and complete, including some UNION, UNION ALL queries INTERSECT. Post of the CREATE TABLE and INSERT statements for all tables using those queries (with the exception of the commonly available rtables, such as those of the scott schema) and a specific question, such as "the UNION query all product...» I expect the UNION query to produce... because... but instead, it produces... Why is this? It seems contractict... manual which says that... ».
-
Hi all
Please I need help with th following question:
WITH some_data LIKE)
SELECT "CNDMNL75P65L736C" FC, "cp" cr, 0 as I1, 1 as I2, I3 OF double 0
UNION ALL
SELECT "PNZGCM74M24L736C", "cp" cr, 5, 0, 0 DOUBLE
UNION ALL
SELECT "," cp, '1', 675,0, 0 DOUBLE cr
UNION ALL
SELECT ", '027113850273' cp," cr, 0, 32, double 0
UNION ALL
SELECT ", '12298850273' cp," cr, 2, 0, 0 DOUBLE
UNION ALL
SELECT ", '35798850273' cp," cr, 0, 12, double 0
UNION ALL
SELECT ", '627771888273' cp," cr, 10, 2, 0 DOUBLE
UNION ALL
SELECT "XDZGCM74M22L736C", "cp" cr, 15, 0, 10 DOUBLE
)
Select * from some_data;
FC CP CR I1 I2 I3 CNDMNL75P65L736C 0 1 0 PNZGCM74M24L736C 5 0 0 1 675 0 0 027113850273 0 32 0 12298850273 2 0 0 35798850273 0 12 0 627771888273 10 2 0 XDZGCM74M22L736C 15 0 10 How can I get a something as; (Only) one record for every 3 rows, like this
CNDMNL75P65L736C 0 1 0PNZGCM74M24L736C 5 0 0 1 675 0 0 (first 3 rows) 027113850273 0 32 0 12298850273 2 0 0 35798850273 0 12 0 (next 3 rows, ) 627771888273 10 2 0 XDZGCM74M22L736C 15 0 10 (and so on )
Thanks in advance
For the 11g version:
WITH some_data AS ( SELECT 'CNDMNL75P65L736C' cf,'' cp ,'' cr, 0 as I1, 1 as I2, 0 as I3 FROM dual UNION ALL SELECT 'PNZGCM74M24L736C' ,'' cp ,'' cr, 5, 0, 0 FROM dual UNION ALL SELECT '' , '' cp ,'1' cr, 675,0, 0 FROM dual UNION ALL SELECT '' , '027113850273' cp ,'' cr, 0 ,32, 0 FROM dual UNION ALL SELECT '' , '12298850273' cp ,'' cr, 2, 0 ,0 FROM dual UNION ALL SELECT '' , '35798850273' cp ,'' cr, 0, 12 ,0 FROM dual UNION ALL SELECT '' , '627771888273' cp ,'' cr, 10, 2 ,0 FROM dual UNION ALL SELECT 'XDZGCM74M22L736C' ,'' cp ,'' cr, 15, 0, 10 FROM dual ) select * from ( select a.*, mod(rownum-1,3)+1 rn, ceil(rownum/3) grp from some_data a ) pivot(max(cf) cf, max(cp) cp, max(cr) cr, max(i1) i1, max(i2) i2, max(i3) i3 for rn in (1 a,2 b,3 c));
GRP A_CF A_CP A_CR A_I1 A_I2 A_I3 B_CF B_CP B_CR B_I1 B_I2 B_I3 C_CF C_CP C_CR C_I1 C_I2 C_I3 1 CNDMNL75P65L736C 0 1 0 PNZGCM74M24L736C 5 0 0 1 675 0 0 2 027113850273 0 32 0 12298850273 2 0 0 35798850273 0 12 0 3 627771888273 10 2 0 XDZGCM74M22L736C 15 0 10 For the 12 c version:
WITH some_data AS ( SELECT 'CNDMNL75P65L736C' cf,'' cp ,'' cr, 0 as I1, 1 as I2, 0 as I3 FROM dual UNION ALL SELECT 'PNZGCM74M24L736C' ,'' cp ,'' cr, 5, 0, 0 FROM dual UNION ALL SELECT '' , '' cp ,'1' cr, 675,0, 0 FROM dual UNION ALL SELECT '' , '027113850273' cp ,'' cr, 0 ,32, 0 FROM dual UNION ALL SELECT '' , '12298850273' cp ,'' cr, 2, 0 ,0 FROM dual UNION ALL SELECT '' , '35798850273' cp ,'' cr, 0, 12 ,0 FROM dual UNION ALL SELECT '' , '627771888273' cp ,'' cr, 10, 2 ,0 FROM dual UNION ALL SELECT 'XDZGCM74M22L736C' ,'' cp ,'' cr, 15, 0, 10 FROM dual ) select * from some_data match_recognize( measures a.cf acf, a.cp acp, a.cr acr, a.i1 ai1, a.i2 ai2, a.i3 ai3, b.cf bcf, b.cp bcp, b.cr bcr, b.i1 bi1, b.i2 bi2, b.i3 bi3, c.cf ccf, c.cp ccp, c.cr ccr, c.i1 ci1, c.i2 ci2, c.i3 ci3 pattern (a b{0,1} c{0,1}) define a as 1=1, b as 1=1, c as 1=1 );
ACF ACP ACR AI1 AI2 AI3 BCF BCP BCR BI1 BI2 BI3 CCF CCP CCR CI1 CI2 CI3 CNDMNL75P65L736C 0 1 0 PNZGCM74M24L736C 5 0 0 1 675 0 0 027113850273 0 32 0 12298850273 2 0 0 35798850273 0 12 0 627771888273 10 2 0 XDZGCM74M22L736C 15 0 10 -
Union all too slow for my query any alternative?
Hello
The following query prints the desired results. What I'm trying to do is to add to my query below is to also retrieve information from different dates (for example 01.01.2012 - 30.4.2012), more information below, but with 0 amounts. The only solution I found is to duplicate the query to a union and entry dates you want below. The problem is that, then the query is too slow.
Any other recommendations are welcome
Thanks in advanceSELECT s.trans_datetime,s.alloc_ref,s.accnt_code,s.treference,s.DESCRIPTN,sum(s.amount*(-1)) as amount,s.conv_code,sum(s.other_amt*(-1)) as other_amt,s.anal_t1,ss.descr, o.NTN_DESCR as flag,z.name as vessel_name FROM accounts s, customers ss,vessel a,nation o, analysis z, customers_anl_cat z1 where s.trans_datetime BETWEEN to_date('01.01.2013','DD.MM.YYYY') AND to_date('30.04.2013','DD.MM.YYYY') AND s.accnt_code=z1.acnt_code AND z1.anl_cat_id=17 AND ss.ACNT_TYPE=2 AND s.accnt_code=ss.acnt_code AND o.NTN_CODE=a.flg_code AND z.anl_code=s.anal_t1 GROUP BY s.trans_datetime,s.alloc_ref,s.accnt_code,s.treference,s.DESCRIPTN,s.conv_code,s.anal_t1,ss.descr ,o.NTN_DESCR,z.name,z1.anl_code
794018 wrote:
Thank you very much for your answers.Unfortunately, the lines of the new date in the amount and need to convert to 0 or null values
OK... What is not eligible for a situation to replicate the query to use UNION all clause You can simply do more in select:
Select column_list1... column_listN, case when s.trans_datetime BETWEEN to_date('01.01.2013','DD.MM.YYYY') AND to_date('30.04.2013','DD.MM.YYYY') then s.amount when s.trans_datetime BETWEEN to_date('01.01.2012','DD.MM.YYYY') AND to_date('30.04.2012','DD.MM.YYYY') then 0 end amount from table_names where (s.trans_datetime BETWEEN to_date('01.01.2013','DD.MM.YYYY') AND to_date('30.04.2013','DD.MM.YYYY') or s.trans_datetime BETWEEN to_date('01.01.2012','DD.MM.YYYY') AND to_date('30.04.2012','DD.MM.YYYY')) Other conditions Follow
-
Poblem with union/union all giving ORA-22950
I use a select statement with the xmlelement to create an xml file.
There the various unions end in 5, but I always bring a line through.
I do like that as then I can use this as a cursor in my plsql without having to create lots of cursors when I only need to use a.
That is to say.
Then, I use a cursor to execute it in a ftp file folder I selected passing ptype as a parameter.SELECT xmlelement("QUOTATION",xmlagg(xmlelement(Quotation, xmlelement(CUSTOMERNAME, customername), xmlelement(QUOTE,quoteid )))xmlfile From cust, quote where custid=quotecustid and ptype = 'Q' UNION SELECT xmlelement("SALES",xmlagg(xmlelement(SALES, xmlelement(CUSTOMERNAME, customername), xmlelement(QUOTE,salesid )))xmlfile From cust, sales where custid=salescustid and ptype = 'S'
If I use the union I get ORA-22950 - I have seen other people use UNION all around it.
If I use union all I'll get a value for the SALE of any line that is
Any ideas how I can get around this as do not want to continue to create cursorsThe use of different sliders is always the best approach IMO.
All things considered, it should be more effective than that appearing more "smart" one.And there is no need to be explicit cursors, it could just be SELECT INTOs wrapped in a PL/SQL CASE statement, with the appropriate exception handler (if necessary).
Anyway, if you want to stick with the single-cursor method, there are different ways to do this:
(1) adding a column selector:
SELECT xmlfile FROM ( SELECT 'Q' as selector , xmlelement("QUOTATION",xmlagg(xmlelement(Quotation, xmlelement(CUSTOMERNAME, customername), xmlelement(QUOTE,quoteid )))xmlfile From cust, quote where custid=quotecustid and ptype = :1 UNION ALL SELECT 'S' , xmlelement("SALES",xmlagg(xmlelement(SALES, xmlelement(CUSTOMERNAME, customername), xmlelement(QUOTE,salesid )))xmlfile From cust, sales where custid=salescustid and ptype = :1 ) WHERE selector = :1 ;
(2) adding a GROUP BY clause, so that XMLAgg returns nothing if no row is selected:
SELECT xmlelement("QUOTATION",xmlagg(xmlelement(Quotation, xmlelement(CUSTOMERNAME, customername), xmlelement(QUOTE,quoteid )))xmlfile From cust, quote where custid=quotecustid and ptype = :1 GROUP BY null UNION ALL SELECT xmlelement("SALES",xmlagg(xmlelement(SALES, xmlelement(CUSTOMERNAME, customername), xmlelement(QUOTE,salesid )))xmlfile From cust, sales where custid=salescustid and ptype = :1 GROUP BY null ;
(3) subqueries:
SELECT case :1 when 'Q' then ( SELECT ... ) when 'S' then ( SELECT ... ) end as xmlfile FROM dual ;
-
UNION ALL GROUP THEN SQL - is a better way
Hi gurus of SQL,.
Just try my luck to see if there is a better way to write the following SQL code. I don't know if the UNION ALL + GROUP BY is the best way. Is it better to use a FULL OUTER JOIN instead?
Thanks for your time.
See you soon
Ligon
... and here's the planSELECT x.task_id, x.task_name, max(x.actual_effort) actual_effort, max(x.date_completed) date_completed, max(x.status) status FROM ( SELECT t.task_id, t.task_name, NULL actual_effort, NULL date_completed, NULL status FROM tt_tbl_tasks t, tt_tbl_emps e, tt_tbl_references r WHERE /*t.task_status = 'Y' AND*/ t.task_start_dt <= menu_util.get_date('15/02/2010',menu_util.df) AND NVL(t.task_end_dt,SYSDATE+9999) >= menu_util.get_date('15/02/2010',menu_util.df) AND e.emp_id = 'MEARS_MP' AND t.task_id = e.task_id AND r.ref_type = 'FREQUENCY' AND t.task_frequency = r.ref_id AND is_event_ready (p_start_dt => t.task_start_dt, p_end_dt => t.task_end_dt, p_check_dt => menu_util.get_date('15/02/2010',menu_util.df), p_freq => to_number(r.ref_name)) = 'Y' UNION ALL SELECT t.task_id, t.task_name, ev.actual_effort, ev.date_completed, ev.status FROM tt_tbl_tasks t, tt_tbl_emps e, tt_tbl_events ev WHERE ev.date_completed = menu_util.get_date('15/02/2010',menu_util.df) AND t.task_id = ev.task_id AND e.emp_id = 'MEARS_MP' AND t.task_id = e.task_id )x GROUP BY x.task_id,x.task_name
Plan SELECT STATEMENT ALL_ROWSCost: 11 Bytes: 178 Cardinality: 2 18 HASH GROUP BY Cost: 11 Bytes: 178 Cardinality: 2 17 VIEW TTDB. Cost: 10 Bytes: 178 Cardinality: 2 16 UNION-ALL 8 NESTED LOOPS 6 NESTED LOOPS Cost: 5 Bytes: 88 Cardinality: 1 4 NESTED LOOPS Cost: 4 Bytes: 65 Cardinality: 1 2 TABLE ACCESS BY INDEX ROWID TABLE TTDB.TT_TBL_TASKS Cost: 4 Bytes: 52 Cardinality: 1 1 INDEX RANGE SCAN INDEX TTDB.TT_TBL_TASKS_IDX_START_DT Cost: 2 Cardinality: 5 3 INDEX UNIQUE SCAN INDEX (UNIQUE) TTDB.TT_TBL_EMPS_PK Cost: 0 Bytes: 13 Cardinality: 1 5 INDEX UNIQUE SCAN INDEX (UNIQUE) TTDB.TT_TBL_REFERENCES_PK Cost: 0 Cardinality: 1 7 TABLE ACCESS BY INDEX ROWID TABLE TTDB.TT_TBL_REFERENCES Cost: 1 Bytes: 23 Cardinality: 1 15 NESTED LOOPS Cost: 5 Bytes: 64 Cardinality: 1 13 NESTED LOOPS Cost: 5 Bytes: 102 Cardinality: 2 10 TABLE ACCESS BY INDEX ROWID TABLE TTDB.TT_TBL_EVENTS Cost: 3 Bytes: 36 Cardinality: 2 9 INDEX RANGE SCAN INDEX TTDB.TT_TBL_EVENTS_IDX_DT_COMPLETED Cost: 1 Cardinality: 2 12 TABLE ACCESS BY INDEX ROWID TABLE TTDB.TT_TBL_TASKS Cost: 1 Bytes: 33 Cardinality: 1 11 INDEX UNIQUE SCAN INDEX (UNIQUE) TTDB.TT_TBL_TASKS_PK Cost: 0 Cardinality: 1 14 INDEX UNIQUE SCAN INDEX (UNIQUE) TTDB.TT_TBL_EMPS_PK Cost: 0 Bytes: 13 Cardinality: 1
Something like that I guess.
select t.Task_ID ,t.Task_Name ,p.Actual_Effort ,p.Date_Completed ,p.Status from ( select t.Task_ID as Task_ID ,t.Task_Name as Task_Name from tt_tbl_Tasks t ,tt_tbl_Emps e ,tt_tbl_References r where t.Task_Start_Dt <= Menu_Util.Get_Date('15/02/2010',Menu_Util.Df) and nvl(t.Task_End_Dt,sysdate + 9999) >= Menu_Util.Get_Date('15/02/2010',Menu_Util.Df) and e.Emp_ID = 'MEARS_MP' and t.Task_ID = e.Task_ID and r.Ref_Type = 'FREQUENCY' and t.Task_Frequency = r.Ref_ID and is_Event_Ready (p_Start_Dt => t.Task_Start_Dt, p_End_Dt => t.Task_End_Dt, p_Check_Dt => Menu_Util.Get_Date('15/02/2010',Menu_Util.Df), p_Freq => to_number(r.Ref_Name)) = 'Y' ) t left join ( select Task_ID ,Task_Name ,Actual_Effort ,Date_Completed ,Status from ( select t.Task_ID as Task_ID ,t.Task_Name as Task_Name ,ev.Actual_Effort as Actual_Effort ,ev.Date_Completed as Date_Completed ,ev.Status as Status ,row_number() over (partition by t.Task_ID, t.Task_Name order by ev.Actual_Effort desc ,ev.Date_Completed desc ,ev.Status desc) rn from tt_tbl_Tasks t ,tt_tbl_Emps e ,tt_tbl_Events ev where ev.Date_Completed = Menu_Util.Get_Date('15/02/2010', Menu_Util.Df) and t.Task_ID = ev.Task_ID and e.Emp_ID = 'MEARS_MP' and t.Task_ID = e.Task_ID ) where rn = 1 ) p on t.Task_ID = p.Task_ID and t.Task_Name = p.Task_Name
The join type and if you filter by null will determine what your require, then its up to you to experiment.
-
UNION ALL in COLLECTION in BULK
My code is like this:SELECT COL_NAME, COUNT BULK COLLECT INTO v_collections FROM ( SELECT 'PROD_NAME' COL_NAME, COUNT(*) COUNT FROM TEST_TABLE WHERE LENGTH(PROD_NAME)>50 UNION ALL SELECT 'PROD_DESC' COL_NAME, COUNT(*) COUNT FROM TEST_TABLE WHERE PROD_DESC IS NULL . . . ..10 MORE UNION ALL ); {code} --does it lead to one context switch or multiple one for each select in the union all --I do want to capture # of errors for each column --although the code runs very fast, still I am worried that it may not be a good coding practice. --is there any better way to do this? --TEST_TABLE has 1 million records Thanks, RN
>
-causes change of context or more for each selection in the union all the
>
A single switch since the entire SQL (i.e. all queries combined set) is sent.
>
is there a better way to do it?
>
It depends on. What you do with the data you are interviewing?
The best way is to use SQL instead of PL/SQL whenever possible. But since we do not know what everything you do has no way to help us.
Maybe you are looking for
-
Whenever I try to download a 'broad' file Firefox continues to ask me: Firefox needs your consent to download large files.Please, click ALLOW to continue with your transfer. If you do not see the application, please click on the icon next to the addr
-
Re: Satellite P870 - screen flickers for a while after the Toshiba homepage
My new Toshiba Satellite P870 starts with screen blinking 1, 2 or 3 times with each start, exactly AFTER. Toshiba, Leading Innovation Logo starts. Can anyone help? Thank you in advance!
-
Ideas: I'm trying to download the updates to my computer, but can't. I get the error code 646 and the download fails. I tried to download the update several times, but get the same answer. What is the problem? Pragrams you have problems with Error me
-
When running java get error (java script false) when trying to uninstall get error message (error application of transformations. Went to sunmicro systems, but can not find help. Also having problems with script errors. I'm debugging the scripts not
-
G62-a13sa, no help from drivers not required please!
HelloI have the laptop mentioned above it was running windows 7 Home premium 64-bit, but I recently did a clean install and instead installed Windows 7 Ultimate 64-bit.The problem I have now I s I have not all drivers either on the laptop I can't eve