Nested group by with conditional query - sql

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).

Related

SQL Multiple left Joins: A to B then A to C

If I have 3 tables A, B and C I understand how to use left join to join them like this:
SELECT *
FROM A LEFT JOIN
B
ON A.col = B.col LEFT JOIN
C
on B.col = C.col
So A to B then B to C
How would I do this:
SELECT *
FROM A LEFT JOIN
B
ON A.col = B.col LEFT JOIN
C
on A.col = C.col
So A to B and then A to C
Would really appreciate any help
I don't see anything wrong with what you're trying to accomplish.
A simple example is at: http://sqlfiddle.com/#!9/6dbbe2/2
There are three tables (A, B, and C):
Table A
id name
1 Alice
2 Bob
3 Carol
4 Don
5 Edith
Table B
id id_A pet
1 5 Tex
2 4 Socks
3 2 Rex
4 1 Percy
5 1 Quinlan
Table C
id id_A hobby
1 1 acting
2 2 boxing
3 4 dancing
4 5 eating
Tables B and C relate to Table A through the id_A foreign key.
A query like you have:
SELECT * FROM A LEFT JOIN B
ON A.id = B.id_a LEFT JOIN C
ON A.id = C.id_a;
works just fine.

How to join 2 table using sql (tried inner join but didn't get result as i wanted)

i have 2 tables for example:
city_A city_B
-------------------
A B
A C
B A
B C
C A
C B
city number_of_covid date
-------------------------------
A 3 2020-02-01
A 6 2020-02-02
B 2 2020-02-01
B 9 2020-02-02
C 4 2020-02-01
C 10 2020-02-02
i want to have something like this :
city_A total_covid_in_A city_B total_covid_in_B date
--------------------------------------------------------------
A 3 B 2 2020-02-01
A 6 B 9 2020-02-02
A 3 C 4 2020-02-01
A 6 C 10 2020-02-02
B 2 A 3 2020-02-01
B 9 A 6 2020-02-02
B 2 C 4 2020-02-01
B 9 C 10 2020-02-02
C 4 A 3 2020-02-01
C 10 A 6 2020-02-02
C 4 B 2 2020-02-01
C 10 B 9 2020-02-02
how to do that using SQL query?
i tried using inner join but didn't get the result that i want
I think this is just some joins:
select t1.city_A, t2a.number_of_covid as total_covid_in_A,
t1.city_B, t2b.number_of_covid as total_covid_in_B,
t2a.date
from table1 t1 join
table2 t2a
on t1.city_a = t2a.city join
table2 t2b
on t1.city_b = t2b.city and t2b.date = t2a.date;
Here is a db<>fiddle.
Your question doesn't explain how the date needs to be linked.. If I were to do a simple join operation, I would also expect a record with "city_a as A, city_b as B and date as '2020-02-02'", but your resultset doesn't show it.. I am assuming you want to assign covid cases count from each day in the alphabetical order of city_b.
The following query will help you achieve the resultset you're looking for:
SELECT c.city_a
,c.total_covid_in_a
,c.city_b
,d.number_of_covid AS total_covid_in_b
,c."date"
FROM
(
SELECT a.city_a
,b.number_of_covid AS total_covid_in_a
,a.city_b
,b."date"
FROM
(
SELECT DISTINCT city_a
,city_b
,ROW_NUMBER() OVER (PARTITION BY city_a ORDER BY city_b ASC) AS rnk
FROM Table1
) a
JOIN (
SELECT DISTINCT city
,number_of_covid
,"date"
,ROW_NUMBER() OVER (PARTITION BY city ORDER BY "date" ASC) AS rnk
FROM Table2
) b
ON a.city_a = b.city
AND a.rnk = b.rnk
) c
JOIN Table2 d
ON c.city_b = d.city
AND c."date" = d."date"
ORDER BY city_a, city_b;

SQL join multiple table

I have 4 tables
A, B, C, D
Table A:
ct_no ct_type
1010. 1
1011. 1
1012. 2
1013. 3
Table B:
ct_no. jcode
1010. 4
1012. 3
1012. 4
1013. 7
1013. 6
1013. 4
Table C:
Jcode jname
4. ABC
3. lol
7. xyz
Table D:
filno orno. fildate. ct_no
12017. 1. 1010
12017. 2. 1010
12017. 3. 1012
42017. 1. 1010
Now I want table d record with table c jname where table c jcode is 3
Output should be
filno orno ctno jnames
12017 1 1012 lol,ABC
Try this:
select d.*, c.jname from tabled d
inner join tableb b on d.ct_no=b.ct_no and b.Jcode=3
inner join tablec c on b.Jcode =c.Jcode
You need a couple of joins:
SELECT d.*
FROM d
JOIN b ON d.ct_no = b.ct_no
JOIN c ON b.jcode = c.jcode
WHERE c.jcode = 3

SQL apply different where condition (filter) for each group in table

i have following SQL table A in my database:
index, group, foo
1 A 2
2 A 2
3 A 0
4 A 1
5 B 2
6 B 1
7 C 1
There are few more groups and I need to write a query based on this filter table B. For each group in table A it's index should be equal or greater than index_egt from table B for the same group.
If the group is not listed in table B, the group won't be filtered.
index_egt, group
3 A
5 B
Expected result:
index, group, foo
3 A 0
4 A 1
5 B 2
6 B 1
7 C 1
Try this, the A.index>=B.index_egt will handle cases where the group is listed in TableB and the B.index_egt IS NULL will handle cases where the group is not listed:
SELECT
A.index,
A.group,
A.foo
FROM TableA AS A
LEFT JOIN TableB AS B ON A.group=B.group
WHERE A.index>=B.index_egt
OR B.index_egt IS NULL
select
a.*
from
A a
left join
B b ON b.group = a.group
where
a.index >= b.index_egt OR b.index_egt IS NULL
I always like this trick with coalesce
SELECT a.*
FROM a_table_with_no_name a
LEFT JOIN b_table_with_no_name b ON b.group = a.group
WHERE a.index >= COALESCE(b.index_egt,a.index)

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