Joining Multiple Tables with different structures?
There are a couple of ways to achieve this, but perhaps the simplest is as Dale K suggested to PIVOT
on tablec before joining to it. To give you an idea how this would work, something along the lines of:
declare @main_table table (id varchar(5), name varchar(5));
declare @tablea table(id varchar(5), val varchar(5));
declare @tableb table(id varchar(5), val varchar(5));
declare @tablec table(id varchar(5), val varchar(5), idx int);
INSERT INTO @main_table
VALUES
('01','bb'),
('02','cc'),
('03','dd'),
('04','ff'),
('05','gg');
INSERT INTO @tablea
VALUES
('01','ab'),
('03','ac'),
('05','ad');
INSERT INTO @tableb
VALUES
('01','ba'),
('02','bc'),
('04','bd');
INSERT INTO @tablec
VALUES
('01','cc',1),
('01','cdf',2),
('01','cba',3),
('03','ggg',1),
('03','dfg',2);
with cte as (
SELECT id, [1], [2], [3], [4]
FROM
@tablec c
PIVOT
(
min(val)
FOR idx
IN ([1], [2], [3], [4])
) pvt
)
SELECT m.id, m.name, a.val AS val_TA, b.val AS val_TB,
c.[1] AS val_TC_index1, c.[2] AS val_TC_index2,
c.[3] AS val_TC_index3, c.[4] AS val_TC_index4
FROM @main_table m
LEFT JOIN @tablea a on a.id = m.id
LEFT JOIN @tableb b on b.id = m.id
LEFT JOIN cte c on c.id = m.id;
I have given a maximum of 4 index columns, but it is easy to see how to extend. If you need this to be open ended, then you will need to convert this into dynamic SQL.
Please note (because you are relatively new) that I have done the hard work for you (providing statements to create the tables and insert the data). In the future when asking such questions, please either do something similar or use db fiddle. You will get many more people willing to help you, if they don't have to do so much typing. Please remember that people are giving you their time for free.
joining multiple tables in an SQL query
Left join 101... and you really....really need to read up on joins if you plan to work in RDMS.
select
b.isbn
,b.title
,b.bookprice
,b.stock
,a.authorname
,o.ordernumber
,o.numcopies
,o.price
from
book b
inner join
BookAuthor ba on
ba.isbn = b.isbn
inner join
Author a on
a.authorid = ba.authorid
left join
orderline o on
o.isbn = b.isbn
left join
bookorder bo on
bo.ordernumber = o.ordernumber
where
b.isbn = 1491936169
Joining multiple tables ORACLE
This would be equivalent (if we also add the additional criteria you mentioned):
FROM
SD
INNER JOIN STORE as S
on S.STOREID = SD.STOREID
INNER JOIN MATERIAL as M
ON M.MATERIALID = SD.MATERIALID
LEFT JOIN STOREBIN as SB
ON SB.STOREBINID = SD.STOREBINID
LEFT JOIN VENDOR as V
ON V.VENDORID = SD.VENDORID
LEFT JOIN MATERIALPRICE as MP
ON MP.MATERIALID = M.MATERIALID
Joining multiple tables with ValidFrom/ValidTo dates (SCD2)
Would you be interested in using SqlServer's geometry
data type to represent time periods? Here I applied it to your example:
WITH c (clientCode, [name], Perd) AS (
SELECT clientCode, [name],
Perd=geometry::STGeomFromText('LINESTRING (' + format(startdate,'yyyyMMdd')+' 0, '+
format(LEAD(startDate, 1, {d '2099-12-31'}) OVER (
PARTITION BY clientCode
ORDER BY startDate) , 'yyyyMMdd') +' 0)', 0)
FROM #Clients),
--- Projects:
p (projectCode, clientCode, [name], Perd) AS (
SELECT projectCode, clientCode, [name],
Perd=geometry::STGeomFromText('LINESTRING (' + format(startdate,'yyyyMMdd')+' 0, '+
format(LEAD(startDate, 1, {d '2099-12-31'}) OVER (
PARTITION BY projectCode
ORDER BY startDate) , 'yyyyMMdd') +' 0)', 0)
FROM #Projects)
SELECT c.clientCode, c.[name] AS clientName,
p.projectCode, p.[name] AS projectName,
startDate=try_cast(format(c.Perd.STIntersection(p.Perd).STEndPoint().STX ,'########') as date),
endDate=try_cast(format(c.Perd.STIntersection(p.Perd).STStartPoint().STX, '########') as date)
FROM
c
inner join
p on
c.clientCode=p.clientCode AND p.Perd.STIntersection(c.Perd).STLength()>0
order by 1,5
This can be easier to nest
as a subquery, and join to another temporal table.
I would imagine that this wouldn't be very fast with very large data-sets, though.
DBT join multiple tables
since clients_last_updated_grouped
doesn't have a where
condition, it's guaranteed to have all of the year/month combinations found in the other models. This makes it much easier. You can just select from that model and join the other models on year and month:
with
updated as (select * from {{ ref('clients_last_updated_grouped') }} ),
deleted as (select * from ),
service as (select * from ),
joined as (
select
updated.year,
updated.month,
updated.client_count,
coalesce(deleted.deleted, 0) as deleted_count,
coalesce(service.service, 0) as service_count
from
updated
left join deleted on updated.year = deleted.year and updated.month = deleted.month
left join service on updated.year = service.year and updated.month = service.month
)
select *
from joined
If your database doesn't support CTEs (with ...
), this becomes:
select
updated.year,
updated.month,
updated.client_count,
coalesce(deleted.deleted, 0) as deleted_count,
coalesce(service.service, 0) as service_count
from
{{ ref('clients_last_updated_grouped') }} as updated
left join {{ ref('clients_deleted_grouped') }} as deleted on updated.year = deleted.year and updated.month = deleted.month
left join {{ ref('clients_service_grouped') }} as service on updated.year = service.year and updated.month = service.month
If it's not the case that clients_last_updated_grouped
has every month/year combination of the other tables, you would need to first construct a "date spine", and then left join all 3 tables to that date spine.
How can I join multiple tables with same primary key to one table with one row per key?
select key1, key2, key3,
tab1.value as value1,
tab2.value as value2,
tab3.value as value3,
tab4.value as value4,
tab5.value as value5,
tab6.value as value6
from tab1 full join
tab2
using (key1, key2, key3) full join
tab3
using (key1, key2, key3) full join
tab4
using (key1, key2, key3) full join
tab5
using (key1, key2, key3) full join
tab6
using (key1, key2, key3);
The using
clause ignores NULL
s for a key value if another value is available, so the complex coalesce()
expressions are not needed. You can then refer to the key values -- without table aliases -- elsewhere in the query.
Related Topics
"You Tried to Execute a Query That Does Not Include the Specified Aggregate Function"
SQL Error: Ora-00933: SQL Command Not Properly Ended
Equivalent Function for Dateadd() in Oracle
How to Do Multiple Case When Conditions Using SQL Server 2008
How Do SQL Exists Statements Work
Disable All Table Constraints in Oracle
Drop All Tables Whose Names Begin with a Certain String
How to Select Date Without Time in SQL
A Way to Extract from a Datetime Value Data Without Seconds
Is There a Nesting Limit for Correlated Subqueries in Some Versions of Oracle
How to Run Multiple Ddl Statements Inside a Transaction (Within SQL Server)
SQL Comma-Separated Row with Group by Clause
How to Populate Calendar Table in Oracle
Varchar Variable Is Not Working in Where Clause