I was given a query that uses some very weird syntax for a join and I need to understand how this join is being used:
SELECT
T1.Acct#
, T2.New_Acct#
, T3.Pool#
FROM DB.dbo.ACCT_TABLE T1
LEFT JOIN DB.dbo.CROSSREF_TABLE T2
INNER JOIN DB.dbo.POOL_TABLE T3
ON T2.Pool# = T3.Pool#
ON T1.Acct# = T2.Prev_Acct#
T1 is a distinct account list
T2 is a distinct account list for each Pool #
T3 is a distinct pool list (group of accounts)
I need to return the previous account number held in T2 for each record in T1. I also need the T3 Pool# returned for each pool.
What I'm trying to understand is why someone would write the code this way. It doesn't make sense to me.
A little indenting will show you better what was intended
SELECT
T1.Acct#
, T2.New_Acct#
, T3.Pool#
FROM DB.dbo.ACCT_TABLE T1
LEFT JOIN DB.dbo.CROSSREF_TABLE T2
INNER JOIN DB.dbo.POOL_TABLE T3
ON T2.Pool# = T3.Pool#
ON T1.Acct# = T2.Prev_Acct#
This is a valid syntax that forces the join order a bit. Basically it is asksing for only the records in table T2 that are also in table T3 and then left joining them to T1. I don't like it personally as it is confusing for maintenance. I would prefer a derived table as I find those much clearer and much easier to change when I need to do maintenance six months later:
SELECT
T1.Acct#
, T2.New_Acct#
, T3.Pool#
FROM DB.dbo.ACCT_TABLE T1
LEFT JOIN (select T2.New_Acct#, T3.Pool#
FROM DB.dbo.CROSSREF_TABLE T2
INNER JOIN DB.dbo.POOL_TABLE T3
ON T2.Pool# = T3.Pool#) T4
ON T1.Acct# = T4.Prev_Acct#
An OUTER APPLY would be clearer here:
SELECT
T1.Acct#,
T4.New_Acct#,
T4.Pool#
FROM DB.dbo.ACCT_TABLE T1
OUTER APPLY
(
SELECT
T2.New_Acct#,
T3.Pool#
FROM DB.dbo.CROSSREF_TABLE T2
INNER JOIN DB.dbo.POOL_TABLE T3 ON T2.Pool# = T3.Pool#
WHERE T1.Acct# = T4.Prev_Acct#
) T4
Related
I know I am doing something wrong, but both tables appear as joins.
This is my code:
SELECT
*
FROM
table1
LEFT OUTER JOIN
users ON users.id = (SELECT id
FROM table2
WHERE type = 'user') t t.id
If I had to a join on the other hand site, its feasible and doable, but for this type, I am not sure I can assign the value like this or not
I don't know if I totally understand the query, but if you are looking to use a join table to connect a many to many relationship try this:
SELECT *
FROM table1 t1
LEFT OUTER JOIN table2 on t1.id = t2.id AND t2.type = 'user'
LEFT OUTER JOIN users u on u.id = t2.id
I'm using SQL server manger.
I have 3 tables
I need a query that pulls t1 ands add an Origin Basin and a Destination Basin.
So far I have the following:
select T1.[Country (destination)], T3.AreaName
From T1
left outer join T2 on
T1.[Country (destination)] = T2.CountryName
inner join T3 on
T2.AreaID = T3.AreaID
inner join T3 on
T2.AreaID = T3.AreaID
Which returns:
Country | Area
However, I'm having trouble doing this for the second country column. I believe you use aliases. I've tried:
select (select AreaName
FROM T3
where T3.AreaID = T2.AreaID) as 'Area Imp',
(select AreaID
From T2
where T2.CountryName = T1.[Country (origin)]) as 'x',
(select AreaID
From T2
where T2.CountryName = T1.[Country (destination)]) as 'y'
FROM T1
But I can't get it to work.
This is what you need to do:
select t1.date, t1.country_destination, t1.country_origin, destination_area.AreaName as area_destination, origin_area.AreaName as area_origin
from t1 as t1 join t2 as destination on t1.country_destination = destination.countryname
join t2 as origin on t1.country_origin = origin.countryname
join t3 as destination_area on t2.areaid = destination_area.areaid
join t3 as origin_area on t2.areaid = origin_area.areaid
You will need to join with the same table twice, both for t2 and t3 so that you get the matching records for your needs.
It helps usually to put aliases that match the purpose of the join (in this case, destination and origin) when writing the query.
I think what you're trying to do is something like this:
select T1.*, T3dest.AreaName, T3orig.AreaName
From
T1
inner join
T2 T2dest on
T1.[Country (destination)] = T2dest.CountryName
inner join
T3 T3dest on
T2dest.AreaID = T3dest.AreaID
inner join
T2 T2orig on
T1.[Country (origin)] = T2orig.CountryName
inner join
T3 T3orig on
T2orig.AreaID = T3orig.AreaID
Note that I've switched to inner joins throughout, at the moment. If you do want left join semantics, you either need to use those for all of the joins to the T2 and T3 tables or you need to change the join order (so that the relevant T3 joins to the T2 tables occur before the attempted join with T1). It's not clear from the sample data if that's required, however.
Try this, You would still want to join on area id's
select T1.Date,T1.[Country (destination)], null [Country (origin)], T3.AreaName [AreaName(Destination)], null [AreaName(Origin)]
From T1
left outer join T2 on
T1.[Country (destination)] = T2.CountryName
inner join T3 on
T2.AreaID = T3.AreaID
union all
select T1.Date,null [Country (destination)], t1.[Country (origin)], Null [AreaName(Destination)], t3. [AreaName(Origin)]
From T1
left outer join T2 on
T1.[Country (Origin)] = T2.CountryName
inner join T3 on
T2.AreaID = T3.AreaID
This question might seem quite trival, but being new to sql programming I'm having some trouble understanding the left joins.
To illustrate, I have the following scenario -
I have to perform left joins on the following tables -
from T1.id to T2.id
from T2.Oi to T3.Oi
from T1.Pi to T4.Pi
from t4.Si to T5.Si
from T6.Ki to T7.Ki
I'm trying to do the following method, but not sure if its correct approach, if so, then not sure if its an efficient approach
select /*(whatever I want)*/
from
T1 left join T2 on T1.id = T2.id
left join T4 on T1.Pi = T4.Pi
left join T5 on T4.Si = T5.Si
left join T3 on T2.Oi = T3.Oi
(Getting stuck on joining T6 and T7)
Can someone help me in understanding if my above approach is right and how solve in joining T6 and T7
Cheers!
joining tables T1..T5 should be like that:
SELECT *
FROM T1
LEFT JOIN T2
ON T2.ID=T1.ID
LEFT JOIN T3
ON T3.OI=T2.OI
LEFT JOIN T4
ON T4.PI=T1.PI
LEFT JOIN T5
ON T5.SI=T4.SI
I don't know what you have in those tables so please consider cartesian product (of course it can be desired result in some cases). Read more here.
I don't know what about tables T6 and T7. If records are in the same form you may want to use UNION (please consider UNION ALL operator - read about difference:
SELECT *
FROM T1
LEFT JOIN T2
ON T2.ID=T1.ID
LEFT JOIN T3
ON T3.OI=T2.OI
LEFT JOIN T4
ON T4.PI=T1.PI
LEFT JOIN T5
ON T5.SI=T4.SI
UNION
SELECT *
FROM T6
LEFT JOIN T7
ON T7.KI=T6.KI
I am trying to JOIN the result of the first SELECT clause, between the first 2 tables (t1 and t2), with the third table (t3):
SELECT t1.*, t2.PropertyCode, t3.TBMonth
FROM Test.dbo.DailyBudgetExtract T1 , Test.dbo.DailyPropertylListExtract T2
WHERE t1.propertyid = t2.proplistid
OR t1.propertyid = t2.propertyid
INNER JOIN Test.dbo.DailyTrialBalanceExtract T3 ON t1.AccCode = t3.AcctCode
What am I doing wrong?
Here is the correct syntax for your query:
SELECT t1.*, t2.PropertyCode, t3.TBMonth
FROM Test.dbo.DailyBudgetExtract T1 JOIN
Test.dbo.DailyPropertylListExtract T2
ON t1.propertyid = t2.proplistid OR t1.propertyid = t2.propertyid INNER JOIN
Test.dbo.DailyTrialBalanceExtract T3
ON t1.AccCode = t3.AcctCode;
The where clause goes after the from clause. But you don't need a where clause, just put the condition in the on clause, where it should go for an explicit join.
This syntax might be clearer:
SELECT
t1.*,
t2.PropertyCode,
t3.TBMonth
FROM
Test.dbo.DailyBudgetExtract T1
JOIN
Test.dbo.DailyPropertylListExtract T2
ON
( t1.propertyid = t2.proplistid
OR
t1.propertyid = t2.propertyid
)
INNER JOIN
Test.dbo.DailyTrialBalanceExtract T3
ON
t1.AccCode = t3.AcctCode
;
Join are part of the projection, not selection (SQL databases make use of some relational algebra). Even if it happens to be executable in some DB (which I donĀ“t think it is) you should avoid it.
You should use EXISTS and NOT EXISTS (which are knows as semi joins) instead.
The query below is a "transliteration" of your query. If it does not return what you want let me know.
SELECT t1.*,
t2.PropertyCode,
t3.TBMonth
FROM Test.dbo.DailyBudgetExtract T1
JOIN Test.dbo.DailyPropertylListExtract T2
ON (t1.propertyid = t2.proplistid OR t1.propertyid = t2.propertyid)
JOIN Test.dbo.DailyTrialBalanceExtract T3
ON t1.AccCode = t3.AcctCode
If you happen to not need the "t3.TBMonth" field
SELECT t1.*,
t2.PropertyCode
FROM Test.dbo.DailyBudgetExtract T1
JOIN Test.dbo.DailyPropertylListExtract T2
ON (t1.propertyid = t2.proplistid OR t1.propertyid = t2.propertyid)
WHERE EXISTS(SELECT 1 FROM Test.dbo.DailyTrialBalanceExtract T3 WHERE t1.AccCode = t3.AcctCode)
TIPS and NOTES:
At least in SQL Server there is no diff between "INNER JOIN" and "JOIN", so pick one and stay with it;
Using "... FROM table1 t1, table t2" is the same as CROSS JOIN;
Avoid having to do JOIN conditions with OR (you do a JOIN [aka INNER JOIN] with your "... FROM table1 t1, table t2" plus "t1.propertyid = t2.proplistid OR t1.propertyid = t2.propertyid") they slow down the query a lot;
I have the following sql statement. I am pulling data from a flat tree structure where i want to select a single follower matching abos_daten.erstellt = (select MAX(erstellt)...
The problem is in order to select the correct MAX(erstellt) I need the following condition where t2.parent_id = t1.parent_id. Unfortunatly t1 can't be bound because it referes to the outer select statement. It seems to create a circle.
select * from trees as t1 inner join abos_daten as starter on t1.parent_id = starter.abonr
right outer join
(select * from trees as t3 inner join abos_daten on t3.child_id = abos_daten.abonr
where abos_daten.erstellt = (select MAX(erstellt) from abos_daten inner join trees as t2 on t2.child_id = abos_daten.abonr
where t2.parent_id = t1.parent_id and abos_daten.status_id <> 147
)
) as follower on t1.child_id = follower.abonr
Does anybody know how to solve this? Kind regards,
jonatan
To start with, t1 doesn't actually refer to the outer select statement; it refers to another entity in the from clause. As it happens, SQL server has a syntax that specifically allows this kind of functionality: cross apply/outer apply. To use this in you situation, you'd want something like this (untested since I can't re-create your tables):
select *
from trees as t1
inner join abos_daten as starter
on t1.parent_id = starter.abonr
outer apply (select MAX(erstellt) as max_erstellt
from abos_daten
inner join trees as t2
on t2.child_id = abos_daten.abonr
where t2.parent_id = t1.parent_id
and abos_daten.status_id <> 14) as t_m
right outer join (select *
from trees as t3
inner join abos_daten
on t3.child_id = abos_daten.abonr) as follower
on t1.child_id = follower.abonr
and t_m.max_erstellt = follower.erstellt