Joining results from 3 tables with same date - sql

I have 3 tables like this:
table1
ID Date Number City
--------------------------------
1 18.11.2019 345 Bristol
table2
ID Date Type Code
-------------------------------
3 18.11.2019 returned 11
table3
ID Date Source Product
----------------------------------
39 18.11.2019 unknown shirt
I would like to write a query that shows a result for the same date on all three tables.
Desired result:
Date table1_Number table1_City table2_Type table2_Code table3_Source table3_Product
18.11.2019 345 Bristol returned 11 unknown shirt

Are you looking for simple joins, as follows?
select
t1.number table1_number,
t1.city table1_city,
t2.type table2_type,
t2.code table2_code,
t3.source table3_source,
t3.product table3_product
from table1 t1
inner join table2 t2 on t1.date = t.date
inner join table3 t3 on t3.date = t.date

Related

Join all record even not match

I have tables_1 and table_2
table_1
id name cost
100 joe 10
101 bob 20
102 mary 30
table_2
id name
100 joe
101 bob
102 mary
103 tom
I want to join these tables even no match id and expect result
id name cost
100 joe 10
101 bob 20
102 mary 30
103 tom null
My query
select t1.id, t1.name, t1.column1, t1.column2
from Table_1 t1
join Table_1 t2 on t1.id = t2.id
and t1.id <> t2.id
I got nothing return. Need some help. Thank you
It looks like you need a simple outer join
select t2.id, t2.name, t1.cost
from table_2 t2
left join table_1 t1 on t1.id=t2.id
What you need is a right join (or a left join if you reverse the order of tables in the join)
select table_2.id, table_2.name, table_1.cost
from table_1 right join table_2
on table_1.id = table_2.id

Join two tables with switch case in order to avoid one to many join

I have two tables, t1 and t2.
Table t1:
Name address id
---- ------- --
rob 32 cgr 12
mary 31 lmo 42
tom axel St 2
Table t2:
ID Flag expense
-- ---- --------
12 Shop 1200
12 Educ 14000
42 educ 4000
Now I will have to create a table which will have attributes from t1 plus two more attributes that is expense in shop and expense in educ
Table t3
Name address id Shop_ex Educ_ex
---- ------- -- ------- -------
rob 32 cgr 12 1200 14000
mary 31 lmo 42 NULL 4000
tom axel st 2 NULL NULL
How to accomplish this?
I tried doing a left join t2 with switch case but it gives me multiple record as the join is becoming one to many.
select
t1.name, t1.address, t1.id,
case
when t2.flag = "shop" then t2.expense
else null
end as shop_ex
case
when t2.flag = "educ" then t2.expense
else null
end as educ_ex
from
t1
left join
t2 on (t1.id = t2.id)
It seems I will have to convert t2 table first before joining, to have a single record on the basis of flag. But I am not sure how to do that.
Please mind the tables are huge and optimized query will be nice.
Please suggest.
You only need to join the first table to the second one, twice:
SELECT t1.Name, t1.address, t1.id, t2a.expense AS Shop_ex, t2b.expense AS Educ_ex
FROM table1 t1
LEFT JOIN table2 t2a
ON t2a.ID = t1.id AND t2a.Flag = 'Shop'
LEFT JOIN table2 t2b
ON t2b.ID = t1.id AND t2b.Flag = 'Educ'
Demo

SQL nested Inner Joins? Or Where Clause On Inner Joins?

I am having an issue with a query I am trying to write. Unfortunately I can only query against the database and cannot change the schema. Here are some simplified example tables:
Table 1
itemID sale date
----------------------------
1 1/2015
1 3/2016
2 5/2016
2 1/2015
Table 2
itemID colorID price
--------------------------------------
1 1 23
1 2 10
1 3 13
2 1 11
2 2 14
2 3 18
Table 3
ColorID color
---------------------------------------
1 Red
2 Blue
3 Green
Table 4
SaleBegin SaleEnd ColorID
----------------------------------------
1/1/2014 12/31/2014 1
1/1/2015 12/31/2015 2
1/1/2016 12/31/2016 3
Now I need a query that essentially gets the price and color for both item ids in the first table. I'm not sure how to do it with this schema even just for one. I tried something like:
SELECT item_id, price, color FROM Table1 T1
INNER JOIN Table2 T2
ON T1.ItemID=T2.ItemID
INNER JOIN Table3 T3
ON T2.ColorID=T3.ColorID
INNER JOIN Table4 T4
ON T3.ColorID=T4.ColorID
WHERE T1.itemID between SaleBegin AND SaleEnd
But it's not working for me, instead giving me every possible color and price for each item. What am I doing wrong? How do I get those values? Expected results should look like:
itemID color price
------------------------------------
1 Blue 10
1 Green 13
2 Green 18
2 Blue 14
http://sqlfiddle.com/#!9/e6fac/4
SELECT t1.itemID
, t3.color
, t2.price
FROM table_1 t1
LEFT JOIN table_2 t2
ON t1.itemID = t2.itemID
LEFT JOIN table_3 t3
ON t2.colorID = t3.colorID
LEFT JOIN table_4 t4
ON t3.colorID = t4.colorID
WHERE t1.sale_date BETWEEN saleBegin and saleEnd;
I'm not sure this is what you're looking for, but this query will give you the itemID, color and price for each product during each sale
SELECT
t4.SaleBegin
,t4.SaleEnd
,t1.itemID
,t3.color
,t2.price
FROM Table4 t4
INNER JOIN Table1 t1
ON t4.SaleBegin = CAST(REPLACE(t1.[sale date], '/', '/1/') AS DATE)
INNER JOIN Table2 t2
ON t1.itemID = t2.itemID
AND t4.ColorID = t2.ColorID
INNER JOIN Table3 t3
ON t4.ColorID = t3.colorID
Here is the SQL Fiddle

Select single row from two table related using mapping table SQL Server

I have three tables: Table1, Table2, Table1Table2Mapping.
Each tabel1 data having multiple data in tabel1, this table1 relation table2 is done through the mapping table the Primary key of the table1 and table2 is put in mapping table.
Table1:
Table1_ID Name ,Other columns
--------- ---- ------
1 Name1
2 Name2
3 Name3
Table2:
Table2_ID Title
--------- -----
101 Title1
102 Title2
103 Title3
104 Title4
105 Title5
Table1Table2Mapping:
Table1_ID Table2_ID
--------- ------------
1 101
1 102
2 103
3 104
3 105
I am getting all the related rows from table1 and its relation in table1 through mappping table
I need to select single row for each Table1 row.
Like this
Table1_ID Name Title
--------- ------- -----
1 Name1 Title1
2 Name2 Title3
3 Name3 Title4
The CROSS APPLY will do the trick:
SELECT
T1.Table1_ID
, T1.Name
, TMP.Title
FROM
Table1 T1
CROSS APPLY (
SELECT TOP(1)
T2.Title
FROM
Table2 T2
INNER JOIN Table1Table2Mapping TTM
ON T2.Table2_ID = TTM.Table2_ID
WHERE
TTM.Table1_ID = T1.Table1_ID
ORDER BY
TTM.TAble2_ID ASC -- You can change this order to what you want
) TMP
You can change the order of the subquery.
SQL Fiddle
Using CROSS APPLY in TechNet
EDIT
IF it is enough, you can use aggregation too:
SELECT
T1.Table1_ID
, T1.Name
, MIN(T2.Title) -- You can use MAX
FROM
Table1 T1
INNER JOIN Table1Table2Mapping TTM
ON TTM.Table1_ID = T1.Table1_ID
INNER JOIN Table2 T2
ON T2.Table2_ID = TTM.Table2_ID
GROUP BY
T1.Table1_ID
, T1.Name
(This gives the same result for the provided dataset, but in real life, the result of this and the previous solution mostly different!
use outer apply in sql server 2005 and later
Select Table1.*, ttt.Title From Table1 Outer Apply
(Select Top 1 Table2.* From Table2 Inner Join Table1Table2Mapping
On Table2.Table2_Id = Table1Table2Mapping.Table2_Id
Where Table1.Table1_Id = Table1Table2Mapping.Table1_Id) ttt

postgreSQL Duplicate rows counting on join

I have one complicated question. I'll try to explain it with example:
have one table that have primary key, and I want to join other table there the first's table primary key is foreign key, and I want If in the second table there is duplicate foreign key to select the number of repeatability. For example:
1-st table:
id name
--- -----
1 Greg
2 Alan
3 George
4 John
5 Peter
2-nd table
id aid data
--- ----- -------
1 2 CCCV
2 2 VVVV
3 3 DDDDD
4 3 SSSS
5 4 PPPPP
I want the result of the join to be:
id(1st table) aid name Data Number
----------- ---- ----- ----- -----
1 null Greg null 1
2 1 Alan CCCV 1
2 2 Alan VVVV 2
3 3 George DDDDD 1
3 4 George SSSS 2
4 5 John PPPPP 1
5 null Peter null 1
I searched a lot, I couldn't find anything. Maybe I do not know how search, or there is no such thing as what I want to do.
SELECT Table1.id, Table2.id as aid, Table1.name, Table2.data,
GREATEST(1, (SELECT COUNT(*)
FROM Table2 t2
WHERE t2.aid = Table1.id
AND t2.id <= Table2.id))
AS number
FROM Table1
LEFT JOIN Table2
ON Table2.aid = Table1.id
ORDER BY id, aid;
works in both MySQL and PostgreSQL.
As per my comment, you've tagged this both MySQL and PostgreSQL.
This answer is for PostgreSQL.
SELECT
table1.id,
table2.aid,
table1.name,
table2.data,
ROW_NUMBER() OVER (PARTITION BY table1.id ORDER BY table2.aid) AS number
FROM
table1
LEFT JOIN
table2
ON table1.id = table2.aid
Queries for PostgreSQL 8.3 which has no window functions.
With bigger tables it is regularly much faster to use a JOIN instead of a correlated sub-query.
The first query aggregates values for Table2 before joining to Table1, which should befaster, too:
SELECT t1.id, t2.aid, t1.name, t2.data, COALESCE(t2.ct, 1) AS number
FROM Table1 t1
LEFT JOIN (
SELECT x.aid, x.data, count(y.aid) + 1 AS ct
FROM Table2 x
LEFT JOIN Table2 y ON x.aid = y.aid AND x.id > y.id
GROUP BY x.aid, x.data
) t2 ON t2.aid = t1.id
ORDER BY t1.id, t2.ct;
And ORDER BY should be fixed.
Alternative without sub-query. Might be faster, yet:
SELECT t1.id, t2.aid, t1.name, t2.data, count(*) + count(t3.id) AS number
FROM Table1 t1
LEFT JOIN Table2 t2 ON t2.aid = t1.id
LEFT JOIN Table2 t3 ON t3.aid = t2.aid AND t3.id < t2.id
GROUP BY t1.id, t2.aid, t1.name, t2.data
ORDER BY t1.id, count(t3.id);
Not sure, didn't test with a bigger set. Test performance with EXPLAIN ANALYZE. Could you report back your results?