Join two tables on a field contais other field - sql

How to join two tables if a field contains other field? Example:
On table A I have a field with data '000;111;222' and on table B I have a field with data '111'.
I want to join like this:
select * from A join B on A.field contains B.field

You could do:
select a.*, b.*
from a
inner join b on b.field = any(string_to_array(a.field, ';'))
The join condition turns a.field to an array, then checks if it contains b.field.

Well perhaps you are giving string_to_array the incorrect parameters. As alternative you can use the POSITION function to find if there is a sbustring match.
with table_a (acol) as ( values('000;111;222'),('000;xxx;222') )
, table_b (bcol) as ( values ('111'),('xxx'),('000'),('123') )
select *
from table_a
join table_b on POSITION(bcol in acol) > 0;

Related

SQL inner join with conditional selection

I am new in SQL. Lets say I have 2 tables one is table_A and the other one is table_B. And I want to create a view with two of them which is view_1.
table_A:
id
foo
1
d
2
e
null
f
table_B
id
name
1
a
2
b
3
c
and when I use this query :
SELECT DISTINCT table_A.id, table_B.name
FROM table_A
INNER JOIN table_B ON table_B.id = table_A.id
the null value in table_A can't be seen in the view_1 since it is not found in table_B. I want view_1 to show also this null row like :
id
name
1
a
2
b
null
no entry
Should I create a 4. table? I couldn't find a way.
Try this Query:
SELECT DISTINCT a.id,(CASE When b.name IS NULL OR b.name = '' Then 'No Entry' else b.name end) name FROM table_A a
LEFT JOIN table_B b on a.id = b.id
You are looking for an outer join. Thus you keep all table_A rows and join table_B rows where they exist. If no match exists, the table_B columns in the joined row are NULL.
You replace NULLs with a value with COALESCE.
SELECT a.id, COALESCE(b.name, 'no entry') AS name
FROM table_a a
LEFT OUTER JOIN table_b b ON b.id = a.id
ORDER BY a.id NULLS LAST;
You haven't tagged your request with your DBMS. Not all DBMS support the NULLS LAST clause.
Please note that there is no DISTINCT in my query. It is not needed. And every time you think you must use DISTINCT, think twice. SELECT DISTINCT is very seldom needed. Most often it is used, because the query is kind of flawed and causes the undesired duplicates itself.

Inner join on ConCat fields

I have table A
Code Range
A 12569
B 18175
C 478931
And Table B
id Type
A12569 0
B18175 1
C478931 0
How can I concatenate the two fields of the first table, in order to join them with the second table.
I have tried with the following query
SELECT concat(A.code,B.Range),b.Type FROM DB.tableA A
inner join DB.tableB B
on Concat(A.code,B.Range)= B.id;
Just concatenate the two columns:
select *
from table_a a
join table_b b on a.code||range = b.id;
The above is standard SQL - not all DBMS respect that though and use a different operator to concatenate strings.
SQL Server:
Select a.Code+b.Range as id, b.Type from TableA a inner join tableB b on a.Code + b.Range = b.id
Untested but should work - presumption is all columns are varchar or nvarchar. May need to add some casting on the range field if that's not the case.

Exclude using joins without subquery

how to converse following code to get the same results using join (without using subquery)
select a_key from table_a a
inner join table_b b --in my code I've 5 joins like that
on a.a_key=b.a_key
where a_key not in
(select a_key from table_c --and conditions within this brackets also
where var_a beteween table_c.col1 and table_c.col2
or var_b beteween table_c.col1 and table_c.col2
)
The following is essentially the same logic:
select a_key
from table_a a inner join
table_b b
on a.a_key = b.a_key left join
table_c c
on (var_a between table_c.col1 and table_c.col2 or
var_b between table_c.col1 and table_c.col2
) and
a.a_key = c.a_key
where c.a_key is null;
You should prefix your columns with table aliases. The column a_key is ambiguous in your original, as are the column var_a and var_b.
These are slightly different if any matching table_c.a_key values are NULL. In that case, the join version probably behaves more like you would expect.

Oracle SQL WITH clause select joined column

SQL:
WITH joined AS (
SELECT *
FROM table_a a
JOIN table_b b ON (a.a_id = b.a_id)
)
SELECT a_id
FROM joined
returns invalid identifier.
How can you select joined column when using WITH clause? I have tried aliases, prefixing and nothing worked. I know I can use:
WITH joined AS (
SELECT a.a_id
FROM table_a a
JOIN table_b b ON (a.a_id = b.a_id)
)
SELECT a_id
FROM joined
but I need this alias to cover all fields.
Only way I managed to meet this condition is using:
WITH joined AS (
SELECT a.a_id a_id_alias, a.*, b.*
FROM table_a a
JOIN table_b b ON (a.a_id = b.a_id)
)
SELECT a_id_alias
FROM joined
but it is not perfect solution...
You can use the effect of the USING clause when joining the tables.
When you join tables where the join columns have the same name (as it is the case with your example), the USING clause will return the join column only once, so the following works:
with joined as (
select *
from table_a a
join table_b b using (a_id)
)
select a_id
from joined;
SQLFiddle example: http://sqlfiddle.com/#!4/e7e099/2
I don't think you can do this without aliases. The result of the "joined" query has two fields, both named a_id. Unless you alias one (or both), as you did in your final query, the outer query has no idea which a_id you are referring to.
Why is your final query not a "perfect" solution?
You can probably use alias as below:
WITH JOINED AS (
SELECT A.A_ID A_A_ID, B.A_ID B_A_ID,
A.FIELD_NAME1 A_FIELDNAME1, A.FIELDNAME2 A_FIELDNAME2,A.FIELDNAME_N A_FIELDNAME_N,
B.FIELD_NAME1 B_FIELDNAME1, B.FIELDNAME2 B_FIELDNAME2,B.FIELDNAME_N B_FIELDNAME_N,
FROM TABLE_A A
JOIN TABLE_B B ON (A.A_ID = B.A_ID)
)
SELECT A_A_ID, B_A_ID
FROM JOINED
IT IS ALWAYS A GOOD PRACTICE TO AVOID USING SELECT *

Hive : Checking if a string from table 1 is present in a list of strings from table 2 while joining two tables

I am trying to join on whether a string(a column from table 1) is present in list of strings(a column from table 2) in Hive QL. Can anyone please help me with the syntax.
SELECT
A.id
FROM tab1 A
inner join tab2 B
ON (
(array_contains(B.purchase_items, A.item_id) = true )
)
Above SQL does not work.
First, unless Hive QL is backwards, your query is wrong upfront:
SELECT A.ID FROM A tab1
will return nothing because you've declared table "A" as "tab1". Either reverse the Alias or correct the table alias reference: (I assume tab1 is the table name, so go with option 1)
SELECT A.ID from tab1 A
--OR
SELECT tab1.id from A tab1
Second, joins do not work based on conditional criteria, they ARE the conditional criteria. Sort of...
For example:
SELECT A.ID
FROM tab1 A
INNER JOIN tab2 B
ON A.item_id = B.purchase_item
is almost like doing a simple cross join with a WHERE condition:
SELECT A.ID
FROM tab1 A, tab2 B --better to use it straight as "FROM tab1 A cross join tab2 B"
WHERE a.item_id = b.purchase_item
You can use LEFT SEMI JOIN, which would retrieve rows from left side table with columns matched from right side table.
SELECT A.id FROM tab1 A
LEFT SEMI JOIN tab2 B
ON A.col1 = B.col1 AND <any-other-join-cond>;
Note that the SELECT and WHERE clauses can’t reference columns from the right hand table.