if else situation in sql - sql

I have a view that I use at work.
My goal is:
If "data on row " = 'petrol' then columns should be fetched from "A table inner join B table"
If "data on row" = 'diesel' then fetch from "C table inner join D table"
Is that possible in same column at the view query? (plsql)
cant i use if else construction for this? problem still not solved because The tables I want to use do not have a common columns
if a =1 then select SAMPLE from sample_table
if a <> 1 then SELECT ANOTHER DIFFRENT from another different unique table

One method would uses left joins and coalesce() for this. Your question doesn't provide many details, but the idea is:
select a.*,
coalesce(b.datas, d.data) as datas
from a left join
b
on . . . and a.column = 'diesel' left join
c
on . . . and a.column <> 'diesel' left join
d
on . . .

Assuming that the columns you require from the tables B and D are of the same data type then you can use UNION ALL with a filter in the WHERE clause:
SELECT a.col1,
a.col2,
b.col3,
b.col4
FROM a INNER JOIN b ON ( a.id = b.id )
WHERE a.other_column = 'petrol'
UNION ALL
SELECT a.col1,
a.col2,
d.col3,
d.col4
FROM a INNER JOIN d ON ( a.id = d.id )
WHERE a.other_column = 'diesel'

Related

Multiple tables joined to a table via single column

I am trying to create query, on below scenario.
with my skills I am able to join Table A,A1,B and A,A1,C and A,A1,D individually and union them.
Is there any better way to achieve same. I am using Oracle as Database.
It all depends on what they mean and if you need to know the columns the values are from.
This would get all the columns and you would have NULL values from the non-matching B, C, D tables:
SELECT *
FROM a1
INNER JOIN a ON a1.aid = a.id
LEFT OUTER JOIN b ON a.extid = b.extid
LEFT OUTER JOIN c ON a.extid = c.extid
LEFT OUTER JOIN d ON a.extid = d.extid
Or, this would get only the relevant values and give you the type they belong to in fewer columns:
SELECT *
FROM a1
INNER JOIN a ON a1.aid = a.id
INNER JOIN (
SELECT extid, 'B' AS type, pqr_col AS col1, qrs_col AS col2 FROM b
UNION ALL
SELECT extid, 'C', abc_col, bcd_col FROM c
UNION ALL
SELECT extid, 'D', xyz_col, yza_col FROM d
) bcd
ON a.extid = bcd.extid
Union was my first thought when I read your question. Though, for simplicity, you could first create a view and then join it to other table(s):
create view v_ext as
select b.extid, b.pqr_col, b.qrs_col from b
union all
select c.extid, c.abc_col, c.bcd_col from c
union all
select d.extid, d.xyz_col, d.yza_col from d;
select *
from a join a1 on a.id = a1.aid
join v_ext v on v.extid = a.extid;
you can try the query with 'with' clause. Something like below, I havent tested it though
with union_output as
( select b.extid, b.pqr_col, b.qrs_col from b
union
select c.extid, c.abc_col, c.bcd_col from c
union
select d.extid, d.xyz_col, d.yza_col from d)
select *
from a join a1 on a.id = a1.aid
join union_output uo on uo.extid = a.extid;
Select *from tableA A
Inner join tableA1 A1 on A1.A1ID=A.AID
Inner join tableB b on b.ExtID=A.ExtID
Inner join tableC c on c.ExtID=A.ExtID
Inner join tableD d on d.ExtID=A.ExtID

SQL join on three tables, lines that exist in 2 tables but not the third

Please I need your help.
Suppose that we have 3 tables A, B and C as shown in the image below:
I want to get lines in the table A that exist or not exist in table B, and lines in table C that exist or not exist in table B, using one sql request.
I have tried this but doesn't work :
SELECT A.ATS0804, C.ATS0207, A.ATS0959, A.ATS0802, B.ATS0827
FROM
ISUT183.ENS0042 B
RIGHT JOIN ISUT183.ENS0038 A
ON B.ENS0038K = A.ATS0804
RIGHT JOIN ISUT183.EN00041 C
ON B.EN00041K = C.AT02812
WHERE ( C.ATS0207 = '0001757430'
AND B.ATS0823 = '9999-01-01'
AND A.ATS0803 = '9999-01-01'
AND A.ATS0959 = '61384352001'
AND A.ATS0802 ='01.01.2010'
) ;
you can do a cross join too:
with AB as (
select * from A left outer join B on A.ID1=B.ID1
),
AC as (
select * from C left outer join B on C.ID2=B.ID2
)
select * from AB CROSS JOIN AC
use where exists and where not exists clauses
If you test equality into table B in where clause, the left outer join or right outer join dont take null
You dont have join between A and C, then you can do a UNION ALL
but you must take columns of same type in selects clause (ID1 same type of ID2)
select * from (
select 'A-B' typejoin, A.ID1 as IDA_OR_C, B.ID1 as IDB from A left outer join B on A.ID1=B.ID1
union all
select 'A-C' typejoin, C.ID2 as IDA_OR_C, B.ID2 as IDB from C left outer join B on C.ID2=B.ID2
) tmp
where ....

Select non duplicate records from a hive join query

I have the following Hive query:
select *
from A
left outer join B
on A.ID = B.ID
where B.ID IS NULL
The result produces duplicate data but I need only non-duplicate records.
After some research, I tried the below query:
select *
from (
select *
from A
left outer join on B
where A.ID = B.ID AND B.ID IS NULL ) join_result
group by jojn_result.ID
It's showing an ambiguous column reference ID error.
I do not have the columns name of table A.
Please help me to identify the solution to this .
Thank you .
Hmmm . . . How about select:
Select A.*
from A left outer join
B
on A.ID = B.ID
where B.ID IS NULL;
I removed the B columns because they are not needed.
One of your join columns may have NULL values. Whenever there is NULL in any of the join key values, it will skip that column. Try replacing the NULL with some default value while joining using NVL or COALESCE. I was looking for same answer and saw your post here. But there was no solution. But since i found the solution I just wanted to post here so that someone can benefit.
select *
from A
left outer join B
on coalesce(A.ID,000) = coalesce(B.ID,000)
where B.ID IS NULL

Hive and selecting non matching records

I have two table like table A , B , i need to select non matching records of A with B ( that is A minus B ) .
A is having multiple columns and B is single column( ID) .
I have tried like below but it is taking too much time
Select * from A where A.ID <> ( select B.ID from B).
And also I have tried
Select * from A left outer join on B where A.ID = B.ID AND B.ID IS NULL
It's showing me wrong result
Please help me to identify solution to this .
Thank you .
use where clause to filter.
Select * from A left outer join B on A.ID = B.ID where B.ID IS NULL

Simulate a left join without using "left join"

I need to simulate the left join effect without using the "left join" key.
I have two tables, A and B, both with id and name columns. I would like to select all the dbids on both tables, where the name in A equals the name in B.
I use this to make a synchronization, so at the beginning B is empty (so I will have couples with id from A with a value and id from B is null). Later I will have a mix of couples with value - value and value - null.
Normally it would be:
SELECT A.id, B.id
FROM A left join B
ON A.name = B.name
The problem is that I can't use the left join and wanted to know if/how it is possible to do the same thing.
you can use this approach, but you must be sure that the inner select only returns one row.
SELECT A.id,
(select B.id from B where A.name = B.name) as B_ID
FROM A
Just reverse the tables and use a right join instead.
SELECT A.id,
B.id
FROM B
RIGHT JOIN A
ON A.name = B.name
I'm not familiar with java/jpa. Using pure SQL, here's one approach:
SELECT A.id AS A_id, B.id AS B_id
FROM A INNER JOIN B
ON A.name = B.name
UNION
SELECT id AS A_id, NULL AS B_id
FROM A
WHERE name NOT IN ( SELECT name FROM B );
In SQL Server, for example, You can use the *= operator to make a left join:
select A.id, B.id
from A, B
where A.name *= B.name
Other databases might have a slightly different syntax, if such an operator exists at all.
This is the old syntax, used before the join keyword was introduced. You should of course use the join keyword instead if possible. The old syntax might not even work in newer versions of the database.
I can only think of two ways that haven't been given so far. My last three ideas have already been given (boohoo) but I put them here for posterity. I DID think of them without cheating. :-p
Calculate whether B has a match, then provide an extra UNIONed row for the B set to supply the NULL when there is no match.
SELECT A.Id, A.Something, B.Id, B.Whatever, B.SomethingElse
FROM
(
SELECT
A.*,
CASE
WHEN EXISTS (SELECT * FROM B WHERE A.Id = B.Id) THEN 1
ELSE 0
END Which
FROM A
) A
INNER JOIN (
SELECT 1 Which, B.* FROM B
UNION ALL SELECT 0, B* FROM B WHERE 1 = 0
) B ON A.Which = B.Which
AND (
A.Which = 0
OR (
A.Which = 1
AND A.Id = b.Id
)
)
A slightly different take on that same query:
SELECT A.Id, B.Id
FROM
(
SELECT
A.*,
CASE
WHEN EXISTS (SELECT * FROM B WHERE A.Id = B.Id) THEN A.Id
ELSE -1 // a value that does not exist in B
END PseudoId
FROM A
) A
INNER JOIN (
SELECT B.Id PseudoId, B.Id FROM B
UNION ALL SELECT -1, NULL
) B ON A.Which = B.Which
AND A.PseudoId = B.PseudoId
Only for SQL Server specifically. I know, it's really a left join, but it doesn't SAY LEFT in there!
SELECT A.Id, B.Id
FROM
A
OUTER APPLY (
SELECT *
FROM B
WHERE A.Id = B.Id
) B
Get the inner join then UNION the outer join:
SELECT A.Id, B.Id
FROM
A
INNER JOIN B ON A.name = B.name
UNION ALL
SELECT A.Id, NULL
FROM A
WHERE NOT EXISTS (
SELECT *
FROM B
WHERE A.Id = B.Id
)
Use RIGHT JOIN. That's not a LEFT JOIN!
SELECT A.Id, B.Id
FROM
B
RIGHT JOIN A ON B.name = A.name
Just select the B value in a subquery expression (let's hope there's only one B per A). Multiple columns from B can be their own expressions (YUCKO!):
SELECT A.Id, (SELECT TOP 1 B.Id FROM B WHERE A.Id = B.Id) Bid
FROM A
Anyone using Oracle may need some FROM DUAL clauses in any SELECTs that have no FROM.
You could use subqueries, something like:
select a.id
, nvl((select b.id from b where b.name = a.name), "") as bId
from a
you can use oracle + operator for left join :-
SELECT A.id, B.id
FROM A , B
ON A.name = B.name (+)
Find link :-
Oracle "(+)" Operator
SELECT A.id, B.id
FROM A full outer join B
ON A.name = B.name
where A.name is not null
I'm not sure if you just can't use a LEFT JOIN or if you're restricted from using any JOINS at all. But as far as I understand your requirements, an INNER JOIN should work:
SELECT A.id, B.id
FROM A
INNER JOIN B ON A.name = B.name
Simulating left join using pure simple sql:
SELECT A.name
FROM A
where (select count(B.name) from B where A.id = B.id)<1;
In left join there are no lines in B referring A so 0 names in B will refer to the lines in A that dont have a match
+ or A.id = B.id in where clause to simulate the inner join