SQL JOIN two tables - sql

I have the following two tables:
table_A
eID
1
2
3
4
table_B
eID dID
1 7
1 5
2 9
2 3
4 8
I want the result to look like this:
eID dID
1 1
1 7
1 5
2 2
2 9
2 3
4 4
4 8
3 3
I was wondering if there is any different way to achieve this than the following:
(SELECT A.eID, A.eID
FROM table_A AS A)
UNION
(SELECT A.eID, B.dID
FROM table_A AS A
INNER JOIN table_B AS B
ON A.eID = B.eID)

I think this is more simply written as:
SELECT A.eID, A.eID as dID
FROM table_A
UNION ALL
SELECT B.eID, B.dID
FROM table B;
But that still isn't allowed for a subquery. I would recommend using a view (or switching to a database that is more ANSI-compliant ;).

Related

Nested group by with conditional query

I have 3 tables:
table: a
id name
2 A
3 B
table: b
id a b
3 2 Asd Ter Gsdt
4 2 Gsd Gsdt Gsda
5 2 Asd Gsd
6 3 Uty Kggs
7 3 Tyud Hffddf
table: c
id a b
6 3 d
7 3 a
8 3 g
9 3 h
10 4 j
11 5 y
12 5 s
13 6 d
14 6 h
expected output:
a b c d
A 2019-04-06 3 a
B 2019-04-06 6 b
I am unsure how to proceed from this, how?
This query do the job, but there is always a question about speed and performance.
select a.name,
(select c_date from c
join b on (c.b_id = b.id)
where b.a = a.id order by c_date desc limit 1) last_c_date,
popular.b_id,
(select photos->0 from b where id = popular.b_id) photo
from a
join (
select distinct on (a)
b.id b_id, a from b
join c on (b.id = c.b_id)
group by b.id, a
order by a, count(*) desc, b.id
) popular on (popular.a = a.id)
order by a.name
If there will be 2 equaly popular b objects in a region, query takes this with smaller id.
If it will be no b object with entries in c than subquery for photo can be surrounded with coalesce (but now it should work too with null value).

Oracle: Joins two tables to duplicate rows for 2 table

I have 2 tables like below:
Table 1
---------
1
2
3
Table 2
--------
A
B
C
How do i join to get an output like below:
Output
---------
1 A
1 B
1 C
2 A
2 B
2 C
3 A
3 B
3 C
Use Cross join:
SELECT *
FROM Table1
CROSS JOIN Table2
You can change the order by replacing * with table fields.
Read more about Cross Join.
OR you could do this:
SELECT Table1.*,Table2.*
FROM Table2,Table1
Result:
ID NAME
1 A
1 B
1 C
2 A
2 B
2 C
3 A
3 B
3 C
You want to do a CROSS JOIN and that will give you the Cartesian product of all the rows.
See http://en.m.wikipedia.org/wiki/Join_(SQL)
select * from table 1,table 2 .
For o/p like A 1
A 2
A 3
B 1
B 2
B 3
C 1
C 2
C 3
just

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

How to count linked entries in another table with a specific value

Let's say I have two tables. A students table and an observations table. If the students table looks like:
Id Student Grade
1 Alex 3
2 Barney 3
3 Cara 4
4 Diana 4
And the observations table looks like:
Id Student_Id Observation_Type
1 1 A
2 1 B
3 3 A
4 2 A
5 4 B
6 3 A
7 2 B
8 4 B
9 1 A
Basically, the result I'd like from the query would be the following:
Student Grade Observation_A_Count
Alex 3 2
Barney 3 1
Cara 4 2
Diana 4 0
In other words, I'd like to gather data for each student from the students table and for each student count the number of A observations from the observations table and tack that onto the other information. How do I go about doing this?
This is a simple join and aggregate:
select
a.Student,
a.Grade,
count(b.Id) as Observation_A_Count
from
Student a left join
Observations b on a.Id = b.Student_Id
group by
a.Student,
a.Grade
order by
1
Or, you can use a correlated subquery:
select
a.Student,
a.Grade,
(select count(*) from observations x where x.Student_Id = a.Id) as Observation_A_Count
from
Student a
order by
a.Student
You can join the table with a specific condition, by doing this you can have a field for Observation_B_Count and Observation_C_Count, etc.
SELECT Student.Student, Student.Grade, COUNT(Observation_Type.*) AS Observation_A_Count
FROM Student
LEFT JOIN Observations ON Observations.Student_ID = Student.Student_ID AND Observations.Observation_Type = 'A'
GROUP BY Student.Student, Student.Grade

Filtering with foreign key

I have three tables tblClients, tblClientsActivities and tblActivities
tblClients and tblClientsActivities are joined together to produce Table A below
SELECT * from tblClientsActivities
left join tblclients on tblClientsActivities.fk_cid=tblclients.pk_cid
PK_AID FK_CID FK_AID
1 4 1
2 4 2
3 4 4
4 5 1
5 5 3
6 5 5
7 6 1
8 6 2
9 7 6
10 8 3
The problem is how do i remove all clients where FK_AID <> 1
Description
Simple use a WHERE clause.
Sample
SELECT * FROM tblClientsActivities
LEFT JOIN tblclients on tblClientsActivities.fk_cid=tblclients.pk_cid
WHERE FK_AID <> 1
With a restriction used in a WHERE clause:
SELECT * from tblClientsActivities
left join tblclients on tblClientsActivities.fk_cid=tblclients.pk_cid
where FK_AID != 1