SQL select is query is not working properly - sql

I am unable to apply a filter(where condition) on the query
SELECT A.Form_Id,
B.CONTAINER_ID,
A.FORM_DESC,
A.FORM_TITLE,
A.LAYOUT,
A.TOTAL_COLUMNS,
COUNT (*) Over () AS Total_Rows
ROW_NUMBER () OVER ( ORDER BY CONTAINER_ID ASC ) ROWNM
FROM FORM_DEFINITION A
LEFT JOIN
(SELECT CONTAINER_ID,FORM_ID FROM FORM_CONTAINER_DEFINITION
) B
ON A.FORM_ID = B.FORM_ID
AND ( ( UPPER(TRIM(A.FORM_ID)) LIKE '%'
|| UPPER(TRIM('FORM2'))
||'%' ) )
In the above code I applied filter like this
( ( UPPER(TRIM(A.FORM_ID)) LIKE '%'
|| UPPER(TRIM('FORM2'))
||'%' ) )
Except this part the query is giving all the info. This filter should show only 'FORM2' row.
But it is showing all the rows as normaly.
.
.
Could you resolve my issue....
.
.
Thanks in advance. :)

Conditions on the first table in a LEFT JOIN need to go in the WHERE clause. On the second table, in the ON clause. Also, the subquery is not necessary. So:
SELECT . ..
FROM FORM_DEFINITION A LEFT JOIN
FORM_CONTAINER_DEFINITION B
ON A.FORM_ID = B.FORM_ID
WHERE UPPER(TRIM(A.FORM_ID)) LIKE '%' || UPPER(TRIM('FORM2')) || '%';
The logic is actually simpler than the above rule. A LEFT JOIN keeps all rows in the first table, regardless of the condition in the ON clause. Matching rows get the values from the second table. Non-matching rows get NULL values.
This is true even when the condition is on the first table.
Also, I would encourage you to use sensible aliases for tables rather than A and B. I would suggest FD and FCD for these two tables.

Related

how to join multiple select statement with full outer join. Error: subquery is returning more than one row

I have this code have been battling with since yesterday, when I unit test each part of this code, it is working, but I need to put them together to generate one output result. This is the full code below : but is giving subquery is returning more than one row.
SELECT NVL(TO_CHAR(D_TRANS.TRANS), 'NULL') AS ID, 'HEADER', D_SPILL.status,
(SELECT L_APPLICATION.APPLICATION
FROM L_APPLICATION L_APPLICATION
WHERE LANGUAGE = 2 AND APPLICATION = D_TRANS.APPLICATION)
AS CASE_TYPE,
NVL(TO_CHAR(D_TRANS.UNIT_IN_CHARGE), 'NULL') AS UNIT_IN_CHARGE,
NVL(TO_CHAR(D_TRANS.PERSON_IN_CHARGE), 'NULL') AS PERSON_IN_CHARGE,
NVL(TO_CHAR(D_TRANS.STATUS), 'NULL') AS CASE_STATUS,
NVL(TO_CHAR(D_TRANS.DEADLINE), 'NULL') AS INTERNAL_DEADLINE,
( select xmlquery('distinct-values(//text())' passing xmldoc returning content).getclobVal()
FROM ( select d_synergi_category.trans,
coalesce(max(case when language = 2 then description end), 'NULL'),
XMLELEMENT(root,xmlagg(XMLELEMENT(e,description,','))
) xmldoc
from L_CASE_CATEGORY
LEFT JOIN d_synergi_category ON d_synergi_category.case_category = L_CASE_CATEGORY.case_category
group by d_synergi_category.trans
)
)
FROM D_TRANS
FULL OUTER JOIN D_SPILL
ON D_TRANS.TRANS=D_SPILL.TRANS
ORDER BY D_TRANS.TRANS DESC;
If I remove the part code below with xmltagg and test both parts of the code separately it is working.
First part working separately
( select xmlquery('distinct-values(//text())' passing xmldoc returning content).getclobVal()
FROM ( select d_synergi_category.trans,
coalesce(max(case when language = 2 then description end), 'NULL'),
XMLELEMENT(root,xmlagg(XMLELEMENT(e,description,','))
) xmldoc
from L_CASE_CATEGORY
LEFT JOIN d_synergi_category ON d_synergi_category.case_category = L_CASE_CATEGORY.case_category
group by d_synergi_category.trans
)
)
Second part working separately is :
SELECT NVL(TO_CHAR(D_TRANS.TRANS), 'NULL') AS ID, 'HEADER',D_SPILL.status,
(SELECT L_APPLICATION.APPLICATION FROM L_APPLICATION
WHERE L_APPLICATION WHERE LANGUAGE = 2
AND APPLICATION = D_TRANS.APPLICATION) AS CASE_TYPE ,
NVL(TO_CHAR(D_TRANS.UNIT_IN_CHARGE), 'NULL') AS UNIT_IN_CHARGE,
NVL(TO_CHAR(D_TRANS.PERSON_IN_CHARGE), 'NULL') AS PERSON_IN_CHARGE,
NVL(TO_CHAR(D_TRANS.STATUS), 'NULL') AS CASE_STATUS ,
NVL(TO_CHAR(D_TRANS.DEADLINE), 'NULL') AS INTERNAL_DEADLINE
FROM D_TRANS
FULL OUTER JOIN D_SPILL
ON D_TRANS.TRANS=D_SPILL.TRANS
ORDER BY D_TRANS.TRANS DESC;
Query (SELECT rtrim(xmlagg( ... must return exactly one row.
We don't have your tables nor data, but it seems that you didn't join its tables (L_CASE_CATEGORY, D_SYNERGI_CATEGORY) with any of tables contained in main query's FROM clause (TRANS, D_SPILL). I suggest you do that and see what happens.
[EDIT]
This is what I meant:
select nvl(to_char(d_trans.trans, 'null') as id,
...,
rtrim(xmlagg(xmlelement(...)) as some_name --> XLM stuff goes here
from l_case_category left join d_synergi_category on ...
join l_case_category on ... --> XML subquery's tables go here,
--> properly joined to other tables
What #Littlefoot said, but I'm going to take a guess at how your tables might be joined, so that you have an example.
SELECT NVL(TO_CHAR(D_TRANS.TRANS), 'NULL') AS ID, 'HEADER',D_SPILL.status,
(SELECT L_APPLICATION.APPLICATION FROM L_APPLICATION
WHERE L_APPLICATION WHERE LANGUAGE = 2
AND APPLICATION = D_TRANS.APPLICATION) AS CASE_TYPE ,
NVL(TO_CHAR(D_TRANS.UNIT_IN_CHARGE), 'NULL') AS UNIT_IN_CHARGE,
NVL(TO_CHAR(D_TRANS.PERSON_IN_CHARGE), 'NULL') AS PERSON_IN_CHARGE,
NVL(TO_CHAR(D_TRANS.STATUS), 'NULL') AS CASE_STATUS ,
NVL(TO_CHAR(D_TRANS.DEADLINE), 'NULL') AS INTERNAL_DEADLINE,
(SELECT rtrim(xmlagg(
XMLELEMENT(e,L_CASE_CATEGORY.DESCRIPTION,',').EXTRACT('//text()')
).GetClobVal(),',')
FROM L_CASE_CATEGORY
INNER JOIN D_SYNERGI_CATEGORY on -- changed
D_SYNERGI_CATEGORY.CASE_CATEGORY = L_CASE_CATEGORY.CASE_CATEGORY
AND L_CASE_CATEGORY.LANGUAGE = 2
WHERE d_synergi_category.trans = D_TRANS.TRANS -- added this line
GROUP BY D_SYNERGI_CATEGORY.CASE_CATEGORY, d_synergi_category.trans) AS CAT_DESC_LIST
FROM D_TRANS
FULL OUTER JOIN D_SPILL
ON D_TRANS.TRANS=D_SPILL.TRANS
ORDER BY D_TRANS.TRANS DESC;
Edit: updated from your comment. This would be a lot easier if you provided table structure and example data.
Your subquery SELECT rtrim(xmlagg(... returns one row per CASE_CATEGORY and trans, because of:
GROUP BY D_SYNERGI_CATEGORY.CASE_CATEGORY, d_synergi_category.trans
When you put it in the main query's select clause, however, you don't want it to return all those rows per main query row, but the one row matching the main query row (just like you find the matching application row with WHERE APPLICATION = D_TRANS.APPLICATION).
So remove the GROUP BY clause and replace it with the WHERE clause instead. Something like
(
SELECT
RTRIM(XMLAGG(
XMLELEMENT(e, cc.description,',').EXTRACT('//text()')
).GetClobVal(),',')
FROM l_case_category cc
JOIN d_synergi_category sc ON sc.case_category = cc.case_category
WHERE sc.case_category = d_spill.case_category -- <=== here
AND sc.trans = d_trans.trans -- <=== and here
and cc.language = 2
)
(Just replace my criteria with your real criteria. Only you know how the tables are related. It is hard for me to even figure it out what the query is supposed to return. I don't understand why you full outer join with D_SPILL in one of the separate queries, without using any of its columns in the select clause. I don't know either why you outer join D_SYNERGI_CATEGORY on L_CASE_CATEGORY.LANGUAGE = 2 in the other query. This seems strange.)

Order BY in Subquery : Missing right parenthese

I try to update 2 columns using a subquery with a specific order so the query is like that:
UPDATE myTable TAO
SET (TAO.BASE_AMT,TAO.TAX_CD_VAT_PCT) = (SELECT SUM(decode(TAX_CD_VAT_PCT,0,0,d.monetary_amount))
, MAX (D.TAX_CD_VAT_PCT)
FROM source1 w
, source2 d
WHERE 1=1
-- Some conditions
GROUP BY d.business_unit, d.voucher_id
ORDER BY d.business_unit, d.voucher_id);
Why am I getting:
ORA-00907: missing right parenthesis
EDIT 1
the query with all conditions :
UPDATE myTable TAO
SET (TAO.BASE_AMT,TAO.TAX_CD_VAT_PCT) = (
SELECT SUM(decode(TAX_CD_VAT_PCT
, 0
, 0
,d.monetary_amount))
, MAX (D.TAX_CD_VAT_PCT)
FROM source1 w
, source2 d
WHERE w.business_unit = TAO.BUSINESS_UNIT
AND d.business_unit = w.business_unit
AND d.voucher_id = w.voucher_id
AND d.VOUCHER_LINE_NUM = w.VOUCHER_LINE_NUM
AND d.VOUCHER_ID = TAO.VOUCHER_ID
GROUP BY d.business_unit, d.voucher_id
ORDER BY d.business_unit, d.voucher_id )
You would appear to want a correlated subquery, because your subquery can return multiple rows.
You don't provide a table layout, but I would expect:
UPDATE myTable TAO
SET (BASE_AMT, TAX_CD_VAT_PCT) =
(SELECT SUM(d.monetary_amount), -- the DECODE does nothing
MAX(D.TAX_CD_VAT_PCT)
FROM source1 w JOIN -- ALWAYS use proper, explicit, standard JOIN syntax
source2 d
ON . . .
WHERE . . . AND
d.business_unit = TAO.business_unit AND
d.voucher_id = TAO.voucher_id
);
Your code is filled with anachronisms and bad practices:
The DECODE() does nothing. If it did, you should use CASE expressions instead.
Commas in JOIN clauses have been obsolete for over fifteen years. Use proper, explicit, standard JOIN syntax.
The ORDER BY in the subquery does nothing.
Subquery have group by clause which can return multiple rows.
Update query cannot take list of values to update.
So, for every unique combination of d.business_unit, d.voucher_id, there will be one row even if you did not select those columns in the inner query.
Also, assuming it returns only one row, you are missing where clause for update query. Only where clause I can see is in subquery.

Oracle sql like multiple conditions with select from other table

I have 375 dialcodes in table "temp":
917277
917278
918083
...
9172738
I can do the following:
select * from cdr where
dnis like 917277% or
dnis like 917278% or
dnis like 918083% or
...
dnis like 9172738%
Is it possible to make a query including "select in" and "like %" conditions?
select * from cdr where dnis in (select dialcode% from temp)
One method is to use exists:
select c.*
from cdr c
where exists (select 1 from temp t where c.dnis like dialcode || '%' );
Note that this does not require distinct, even when there might be multiple matches.
You can use JOIN and LIKE to achieve similiar result:
SELECT c.* -- DISTINCT may be needed if dialcodes overlap each other
FROM cdr c
JOIN temp t
ON c.dnis LIKE t.dialcode || '%'

Combine SQL query result with another query statement under one query? (Complicated)

I currently want to combine two SQL queries into one. This is a bit similar to SQL: Taking the result of of query and using it another - combine. Suppose there are two queries:
SQL Statement
1.) SELECT *
FROM (SELECT B.example1
FROM EXAMPLE1A A
INNER JOIN EXAMPLE1B B ON A.ID = B.ID
WHERE A.ABC ='ABC'
ORDER BY A.ORDER_BY ) as colstate
2.) SELECT colstate
FROM EXAMPLE_TABLE
WHERE EFG LIKE '%'
AND BGTHAN >= '1'
AND SMTHAN <= '100'
ORDER BY ORDER_BY ASC
I want to use the result in query 1.) as the colstate (column statement) in query 2.). But:
What Have I tried is:
SELECT (SELECT B.example1
FROM EXAMPLE1A A
INNER JOIN EXAMPLE1B B
ON A.ID = B.ID
WHERE A.ABC ='ABC'
ORDER BY A.ORDER_BY )
FROM EXAMPLE_TABLE
WHERE EFG LIKE '%'
AND BGTHAN >= '1'
AND SMTHAN <= '100'
ORDER BY ORDER_BY ASC
And it turns out to be Error: Scalar subquery is only allowed to return a single row, how should I replace the "=" into "IN"? Or is my statement totally wrong?
"Combine two queries into one" - that's not a good specs. Try to find out what exactly you want to get as a FLAT 2-dimensional table, think of nested SELECTs as of nested loops where the inner one can only set a single value for parent's row. Like this:
[Outer loop - parent row]
[Inner loop - children rows]
// all you can do here is change a single parent's field to anything
// like constant/sum/avg/topmost/ugly-subquery-returning-a-single-result
[/Inner loop]
[/Outer loop]
The error says that query you are using as column statement must return at most a single row.
It should probably look something like this:
SELECT (SELECT B.example1
FROM EXAMPLE1A A
INNER JOIN EXAMPLE1B B
ON A.ID = B.ID
WHERE A.ABC ='ABC'
AND A.SOME_COLUMN = E.SOMECOLUMN // retrieve only relevant data for this row
ORDER BY A.ORDER_BY )
FROM EXAMPLE_TABLE E
WHERE EFG LIKE '%'
AND BGTHAN >= '1'
AND SMTHAN <= '100'
ORDER BY ORDER_BY ASC

Understanding a basic SQL query

I have a query like
SELECT tran_number
FROM table_a WHERE customer_id IN
(SELECT customer_id
FROM table_b
WHERE customer_key = 89564
AND ( other_phn_area_code
|| other_phnum_pfx_num
|| other_phnum_sfx_num IN
(123456789)))
AND phn_area_code || phnum_pfx_num || phnum_sfx_num IN (123456789)
The above code is working fine. The concern is with the inner query (copied inner query alone below)...
(SELECT customer_id
FROM table_b
WHERE customer_key = 89564
AND ( other_phn_area_code
|| other_phnum_pfx_num
|| other_phnum_sfx_num IN
(123456789)))
When i execute this query, i'm getting error as customer_id: invalid identifier. In real, table_b is not having any field named customer_id. If so, then how it is working, without any issue, when i use it as an inner query above.
Please help me to understand this.
Database details below
Oracle 11G Enterprise edition 11.2.0.2.0
PL/SQL Release 11.2.0.2.0
if the where condition of that inner select has a result, then the column customer_id from table_a will be selected.
If not then it won't be selected. The outer select checks that with the in condition. That is like saying: "Only return something if the inner select return true."
It's a matter of scope. Oracle validates identifiers starting with the innermost sub-query and working outwards. If we add table aliases to your original query things might become clearer:
SELECT t1.tran_number
FROM table_a t1
WHERE t1.customer_id IN
(SELECT t1.customer_id
FROM table_b t2
WHERE t2.customer_key = 89564
AND ( t2.other_phn_area_code
|| t2.other_phnum_pfx_num
|| t2.other_phnum_sfx_num IN
(123456789)))
AND t1.phn_area_code || t1.phnum_pfx_num || t1.phnum_sfx_num IN (123456789)
In effect, the outer query is using the sub-querty as a test for EXISTS, i.e. just checking for the existence of a given value of CUSTOMER_KEY and those other columns. If this is not what you want then you should change the column name in the sub-query. (And that's a pretty good bet: you're probably getting puzzling results from the main query and that's why you're investigating the sub-query in isolation).
Using aliases in these scenarios is always good practice. If you had aliased the sub-query like this:
....
WHERE t1.customer_id IN
(SELECT t2.customer_id
FROM table_b t2
WHERE t2.customer_key = 89564
....
the error would have been immediately apparent.
The SQL Reference does explain the operation of scope in sub-queries, but it's hard to find. What it says is this:
"Oracle resolves unqualified columns in the subquery by looking in
the tables named in the subquery and then in the tables named in the
parent statement"
You can find a clearer explanation of scoping in the PL/SQL documentation; SQL sub-queries work in the same fashion. Find out more.
Thats is a known bug with IN. If you use table alias you will get error
SELECT tran_number
FROM table_a WHERE customer_id IN
(SELECT b.customer_id
FROM table_b b
WHERE customer_key = 89564
AND ( other_phn_area_code
|| other_phnum_pfx_num
|| other_phnum_sfx_num IN
(123456789)))
AND phn_area_code || phnum_pfx_num || phnum_sfx_num IN (123456789)
Also use EXISTS to avoid this type of silent behaviour
SELECT tran_number
FROM table_a as t1 WHERE EXISTS
(SELECT *
FROM table_b as b
WHERE customer_key = 89564
AND ( other_phn_area_code
|| other_phnum_pfx_num
|| other_phnum_sfx_num IN
(123456789))
AND b.customer_id =t1.customer_id)
AND phn_area_code || phnum_pfx_num || phnum_sfx_num IN (123456789)