How to join 2 tables with no common column in sql - sql

eg
Names
id | name
1 abc
2 efg
Area
id | areaName
3 area1
4 area2
The query should return
id | name | areaid
1 abc 3
1 abc 4
2 efg 3
2 efg 4

This should give the ecpected result:
select a.id, a.name, b.id from names,area

When you want to join all records from table A to all records from table B (i.e. get a Cartesian product, you can use CROSS JOIN:
SELECT Names.id, Names.name, Area.areaid
FROM Names
CROSS JOIN Area
ORDER BY Names.id, Area.areaid

Related

How to write SQL to select a value in table B if not exists in table A otherwise select value in table A?

I want to get a default rate for activity or an override rate if one exists in another table. How can I write SQL for this?
I have this query but it produces an error "every derived table must have its own alias".
select A.id, rate from (
select
A.id, coalesce(B.rate, A.rate) as rate
from
A
left join B on B.id = A.id
);
Consider the following data
table user
user_id name
1 johnny
2 sam
table activity_types
activity_type_id description rate
1 cook steak $12.00
2 flip burgers $9.00
3 wait tables $8.00
4 wash dishes $8.00
table personal_override_rates
user_id activity_type_id rate
1 1 $18
table activities
activity_id user_id activity_type_id qty
1 1 1 1
2 1 2 1
3 2 1 1
4 2 2 1
desired result:
johnny cook steak 1 $18.00
johnny flip burgers 1 $9.00
sam cook steak 1 $12.00
sam flip burgers 1 $9.00
The error you get is because you have a derived table without an alias. You must provide one and then select the id and rate using the alias.
Like this:
select derived_table.id, derived_table.rate from (
select
A.id, coalesce(B.rate, A.rate) as rate
from
A
left join B on B.id = A.id
) as derived_table;

Joing on SQL table with arrays

I have two SQL tables
TABLE A
id | user | embedding
-----------------------
1 Ram [.12,.56]
2 Shyam [.23,.24]
3 Ghanshyam [.23,.39]
4 Balram [.34,.39]
TABLE B
--------------------
id | users
--------------------
1 [Ram,Shyam]
2 [Ram,Ghanshyam]
3 [Ram, Balram]
And I want to have a query that will return essentially table B but with the users replaced by their embeddings.
Desired output
-----------------------------
id | users
-----------------------------
1 [[.12,.56],[.23.,.24]]
2 [[.12,.56],[.23,.39]]
3 [[.12,.56], [.34,.39]]
How can I do this?
how about using unnest and array_agg:
select b.id , array_agg(embedding)
from TableB b
cross join unnest(b.users) c(user)
join TableA a
on c.users = a.user
group by b.Id

Using multiple joins (e.g left join)

I would like to know what's the logic for multiple joins (for example below)
SELECT * FROM B returns 100 rows
SELECT B.* FROM B LEFT JOIN C ON B.ID = C.ID returns 120 rows
As I know using left join will returns any matching data from the left table which is B if data are found for both table. But how come when using left join, it returns more data than table B itself?
What am I do wrong or misunderstood here? Any guidance are very appreciated. Thanks in advance.
Let be table B:
id
----
1
2
3
Let be table C
id name
------------
1 John
2 Mary
2 Anne
3 Stef
Any id from b is matched with ids from c, then id=2 will be matched twice. So a left join on id will return 4 rows even if base table B has 3 rows.
Now look at a more evil example:
Table B
id
----
1
2
2
3
4
table C
id name
------------
1 John
2 Mary
2 Anne
3 Stef
Every id from b is matched with ids from c, then first id=2 will be matched twice and second id=2 will be matched twice so the result of
select b.id, c.name
from b left join c on (b.id = c.id)
will be
id name
------------
1 John
2 Mary
2 Mary
2 Anne
2 Anne
3 Stef
4 (null)
The id=4 is not matched but appears in the result because is a left join.
Look at the following example :
B = {1,2}
C = {(1,a),(1,b),(1,c),(1,d),(1,e)}
The result of B left join C will be :
1 | a
1 | b
1 | c
1 | d
1 | e
2 | null
The number of rows in the result is definitely larger than rows in B (2).
In general the number of rows in result of B left join C is bounded by B.size + C.size and not only by B.size as you think...
As per your query it do the join to B Table with C and B table is Left Table so it will display all the records of Left table in our case it is B and related from other Table in our Case it is C.

comparing rows in sql on two different columns

id address retailer
1 A 11
2 A 11
3 A 11
4 A 12
5 A 13
6 B 12
7 B 12
8 B 13
My output should be
id address retailer
1 A 11
4 A 12
5 A 13
6 B 12
8 B 13
i.e my query should return id's which have same address but not same retailer.
How toget this?
Try to use group by clause as below:
select min(id), address, retailer
from tab
group by address, retailer
Assuming you're joining on columns with no duplicates, which is by far the most common case:
An inner join of A and B gives the result of A intersect B, i.e. the inner part of a venn diagram intersection.
An outer join of A and B gives the results of A union B, i.e. the outer parts of a venn diagram union.
Examples:
Suppose you have two Tables, with a single column each, and data as follows:
A B
- -
1 3
2 4
3 5
4 6
Note that (1,2) are unique to A, (3,4) are common, and (5,6) are unique to B.
Inner join:
An inner join using either of the equivalent queries gives the intersection of the two tables, i.e. the two rows they have in common.
select *
from a
INNER JOIN b on a.a = b.b;
select a.*,b.*
from a,b
where a.a = b.b;
a | b
--+--
3 | 3
4 | 4
Left outer join:
A left outer join will give all rows in A, plus any common rows in B.
select *
from a
LEFT OUTER JOIN b on a.a = b.b;
select a.*,b.*
from a,b
where a.a = b.b(+);
a | b
--+-----
1 | null
2 | null
3 | 3
4 | 4
Full outer join:
A full outer join will give you the union of A and B, i.e. All the rows in A and all the rows in B. If something in A doesn't have a corresponding datum in B, then the B portion is null, and vice versa.
select *
from a
FULL OUTER JOIN b on a.a = b.b;
a | b
-----+-----
1 | null
2 | null
3 | 3
4 | 4
null | 6
null | 5
select min(id) as id,address, retailer
from table1
group by address, retailer
order by id
The query you need is:
SELECT min(id), address, retailer
FROM table1 AS t1
group by address, retailer
order by address
Here's the source
Use This: It's working:
SELECT * FROM `sampletable` GROUP BY address, retailer

SQL Select values associated with keys from other table

I have a mapping table tableA
key value
-----------
1 "John"
2 "George"
3 "Kate"
4 "loves"
5 "hates"
and another tableB that contains rows based on keys of tableA
col1 col2 col3
------------------
1 5 2
2 4 3
3 4 1
I want to write a selection query which will return rows from table B but replaced with their appropriate values.
e.g. the output has to be:
John | hates | George
George | loves | Kate
Kate | loves | John
Thank you.
SELECT A1.value, A2.value, A3.value
FROM tableB
JOIN tableA as A1 ON tableB.col1 = A1.key
JOIN tableA as A2 ON tableB.col2 = A2.key
JOIN tableA as A3 ON tableB.col3 = A3.key;
You should probably put the last 2 items, 'loves' and 'hates', into a separate table as they represent a different type of data than the other 3.
Here are the tables:
users:
id name
----------
1 John
2 Edward
3 Kate
feelings:
id type
----------
1 love
2 hate
feelings_users:
id user1_id feeling_id user2_id
-----------------------------------
1 1 2 2
2 2 1 3
3 3 1 1
and here's the query:
select `Ua`.`name`, `F`.`type`, `Ub`.`name` from `feelings_users` as `X`
left join `users` as `Ua` on `X`.`user1_id` = `Ua`.`id`
left join `feelings` as `F` on `X`.`feeling_id` = `F`.`id`
left join `users` as `Ub` on `X`.`user2_id` = `Ub`.`id`
and it will output:
name type name
--------------------
John hate Edward
Edward love Kate
Kate love John