How to use like operator outside SELECT - oracle

I have the following query which works fine.
SELECT A.*
FROM
(
SELECT 'ABC','DEF' FROM DUMMY
UNION ALL
SELECT col1,col2 FROM DUMMY
) A;
I want to apply the like key word on the first column returned by the nested query. I tried the following:
SELECT col1, col2
FROM
(
SELECT 'ABC','DEF' FROM DUMMY
UNION ALL
SELECT col1,col2 FROM DUMMY
) A
WHERE COL1 LIKE 'A%';
But the above query did not work. I'm getting the error: ORA-00904: "COL1": invalid identifier.
The fiddle link for the same is as follows: http://sqlfiddle.com/#!4/1c54b/7
Please could anybody guide me on how I can achieve the same?
Edit: I'm also trying to get the columns from the existing table as well.
Thanks in advance.

When using union, column names or aliases have to be matched on both tables.
You can call already defined column names and aliases.
Do not forget define column alias('ABC' as col1)
SELECT col1, col2
FROM
(
SELECT 'ABC' as col1,'DEF' as col2 FROM DUMMY
UNION ALL
SELECT 'GHI' as col1,'JKL' as col2 FROM DUMMY
) A
WHERE COL1 LIKE 'A%';
I think you are trying something like;
SELECT col1, col2
FROM
(
SELECT col1,col2 FROM DUMMY
UNION ALL
SELECT col1,col2 FROM DUMMY2
) A
WHERE col1 LIKE 'A%';
Have a look at another sample from me on here

Related

Oracle Select unique on multiple column

How can I achieve this to Select to one row only dynamically since
the objective is to get the uniqueness even on multiple columns
select distinct
coalesce(least(ColA, ColB),cola,colb) A1, greatest(ColA, ColB) B1
from T
The best solution is to use UNION
select colA from your_table
union
select colB from your_table;
Update:
If you want to find the duplicate then use the EXISTS as follows:
SELECT COLA, COLB FROM YOUR_TABLE T1
WHERE EXISTS (SELECT 1 FROM YOUR_tABLE T2
WHERE T2.COLA = T1.COLB OR T2.COLB = T1.COLA)
If I correctly understand words: objective is to get the uniqueness even on multiple columns, number of columns may vary, table can contain 2, 3 or more columns.
In this case you have several options, for example you can unpivot values, sort, pivot and take unique values. The exact code depends on Oracle version.
Second option is listagg(), but it has limited length and you should use separators not appearing in values.
Another option is to compare data as collections. Here I used dbms_debug_vc2coll which is simple table of varchars. Multiset except does main job:
with t as (select rownum rn, col1, col2, col3,
sys.dbms_debug_vc2coll(col1, col2, col3) as coll
from test )
select col1, col2, col3 from t a
where not exists (
select 1 from t b where b.rn < a.rn and a.coll multiset except b.coll is empty )
dbfiddle with 3-column table, nulls and different test cases

Fetch name based on comma-separated ids

I have two tables, customers and products.
products:
productid name
1 pro1
2 pro2
3 pro3
customers:
id name productid
1 cust1 1,2
2 cust2 1,3
3 cust3
i want following result in select statement,
id name productid
1 cust1 pro1,pro2
2 cust2 pro1,pro3
3 cust3
i have 300+ records in both tables, i am beginner to back end coding, any help?
Definitely a poor database design but the bad thing is that you have to live with that. Here is a solution which I created using recursive query. I don't see the use of product table though since your requirement has nothing to do with product table.
with
--Expanding each row seperated by comma
tab(col1,col2,col3) as (
Select distinct c.id,c.prdname,regexp_substr(c.productid,'[^,]',1,level)
from customers c
connect by regexp_substr(c.productid,'[^,]',1,level) is not null
order by 1),
--Appending `Pro` to each value
tab_final as ( Select col1,col2, case when col3 is not null
then 'pro'||col3
else col3
end col3
from tab )
--Displaying result as expected
SELECT
col1,
col2,
LISTAGG(col3,',') WITHIN GROUP( ORDER BY col1,col2 ) col3
FROM
tab_final
GROUP BY
col1,
col2
Demo:
--Preparing dataset
With
customers(id,prdname,productid) as ( Select 1, 'cust1', '1,2' from dual
UNION ALL
Select 2, 'cust2','1,3' from dual
UNION ALL
Select 3, 'cust3','' from dual),
--Expanding each row seperated by comma
tab(col1,col2,col3) as (
Select distinct c.id,c.prdname,regexp_substr(c.productid,'[^,]',1,level)
from customers c
connect by regexp_substr(c.productid,'[^,]',1,level) is not null
order by 1),
--Appending `Pro` to each value
tab_final as ( Select col1,col2, case when col3 is not null
then 'pro'||col3
else col3
end col3
from tab )
--Displaying result as expected
SELECT
col1,
col2,
LISTAGG(col3,',') WITHIN GROUP( ORDER BY col1,col2 ) col3
FROM
tab_final
GROUP BY
col1,
col2
PS: While using don't forget to put your actual table columns as in my example it may vary.

Change Default Hive result to some values

I was trying to get duplicate record count from table, but for particular partitions data is not available, so hive is only printing "OK" result.
Is it possible to change this result with some value like 0 Or NULL.
Yes have tried with nvl,COALESCE,case option still it showing OK. AND goal is to only check duplicate count, so required at least one value
select col1, col2, nvl(count(*),0) AS DUPLICATE_ROW_COUNT, 'xyz' AS TABLE_NAME
from xyz
where data_dt='20170423'
group by col1,col2
having count(*) >1
It will return no rows on empty dataset because you are using group by and having filter. Group by having nothing to group, that is why it does not return any rows. Without group by and having query returns 0:
select nvl(count(*),0) cnt, 'xyz' AS TABLE_NAME
from xyz
where data_dt='20170423'
As a solution you can UNION ALL with null row when empty dataset
select col1, col2, nvl(count(*),0) AS DUPLICATE_ROW_COUNT, 'xyz' AS TABLE_NAME
from xyz
where data_dt='20170423'
group by col1,col2
having count(*) >1
UNION ALL --returns 1 row on empty dataset
select col1, col2, DUPLICATE_ROW_COUNT, TABLE_NAME
from (select null col1, null col2, null AS DUPLICATE_ROW_COUNT, 'xyz' AS TABLE_NAME
)a --inner join will not return rows when non-empty dataset
inner join (
select count(*) cnt from --should will return 0 on empty dataset
( --your original query
select col1, col2, nvl(count(*),0) AS DUPLICATE_ROW_COUNT, 'xyz' AS TABLE_NAME
from xyz
where data_dt='20170423'
group by col1,col2
having count(*) >1
)s --your original query
)s on s.cnt=0
Also it's may be possible to use CTE (WITH) and WHERE NOT EXISTS instead of inner joinfor your subquery, didn't test it.
Also you can use shell to get result and test it on empty value:
dataset=$(hive -e "set hive.cli.print.header=false; [YOUR QUERY HERE]);
# test on empty dataset
if [[ -z "$dataset" ]] ; then
dataset=0
fi

Distinct in XMLAGG function in oracle sql

problem in avoiding duplicates using XMLAGG function
A table which is having multiple records. where each record has one column contains repetitive date.
Using XMLAGG function in the following sql
select col1, col2, XMLAGG(XMLELEMENT(E, colname || ',')).EXTRACT('//text()')
from table
group by col1, col2
i get the following output
col1 col2 col3
hareesh apartment residential, commercial, residential, residential
But i need the following output as
col3 : residential, commercial.
Anyone help me
Try using a subquery to remove duplicates:
SELECT col1, col2, XMLAGG(XMLELEMENT(E, colname || ',')).EXTRACT('//text()')
FROM (SELECT DISTINCT col1, col2, colname FROM table)
GROUP BY col1, col2

Generate difference between 2 tables listing columns from both tables

Have 2 tables with same columns and want to generate the difference between the tables and want to show the difference listing all columns from both tables
example:
select a.*,b.* from (
(
select a.col1,a.col2 from
(select col1, col2 from table1 minus select col1, col2 from table2) as a
)
union
(
select b.col1, b.col2 from
(select col1, col2 from table2 minus select col1, col2 from table2) as b
)
)
The result should be
a.col1 a.col2 b.col1 b.col2
a.FName a.ZipCode b.FName b.ZipCode
John <same value> Jane <same value as A>
Alpha 1234 Beta 2345
My query returns exception that it is missing R parenthesis after the 1st minus keyword
I think you are trying to find rows from table a which are missing in table b and rows in table b which are missing from table a. However, there is no point in joining these two sets. Try the following query and see if it works for you.
SELECT col1, col2, 'Missing from table 2' title
FROM
(
SELECT col1,
col2
FROM table1
MINUS
SELECT col1,
col2
FROM table2
)
UNION ALL
SELECT col1, col2, 'Missing from table 1' title
FROM
(
SELECT col1,
col2
FROM table2
MINUS
SELECT col1,
col2
FROM table1
)

Resources