SQL JOIN USING and WHERE - sql

This is somewhat of a followon to SQL JOIN where to place the WHERE condition?
I would prefer to use the USING clause on the join, but am not yet able to put the field value condition with the join.
SELECT 1
FROM table1 t1
JOIN table2 t2 USING(id) AND t2.field = 0;
ORA-00933: SQL command not properly ended
Is it possible to have USING and another condition as part of the JOIN clause?

You can use:
SELECT 1
FROM table1 t1
JOIN table2 t2 USING(id)
WHERE t2.field = 0;
Using USING(id) is like using ON t1.id = t2.id except that in the JOIN result instead of two columns t1.id & t2.id there is only one id column.
For INNER JOIN USING with a condition followed by an OUTER JOIN you need a subquery to keep the WHERE with the USING:
SELECT ...
FROM (SELECT id, ...
FROM table1 t1
JOIN table2 t2 USING(id)
WHERE t2.field = 0) s
LEFT JOIN ...;
For an OUTER JOIN USING with a condition you need a subselect:
SELECT ...
FROM table1 t1
LEFT JOIN (SELECT *
FROM table2 t2
WHERE t2.field = 0) t2
USING (id);
See this re ON/WHERE with JOIN. See this re ON/WHERE when mixing INNER & OUTER JOINs.

Related

SQL multiple left join + join with a select

I'm new to SQL. I need help with left join with an select.
The part I'm interested in:
Select...
from table t1
left join table t2
on t1.id=t2.id,
left join (select * from table 3 where ...) t3
on t1.id=t3.id
where t1.id='something'
Also i tried to moved in the where clause the t1.id(+)=t3.id but didn't work.
I think the logic you want is:
Select...
from t1 left join
t2
on t1.id = t2.id left join
t3
on t1.id = t3.id and
<t3 conditions go here>
where t1.id = 'something'
You have a superfluous comma -- and commas should never be in the FROM clause.
You also have a superfluous subquery. You can get the same functionality by just including the condition in the ON clause.

HQL query with Left Join in NHibernate 2

How can I give conditions for left join in NHibernate 2.0 HQL query.
Eg in SQL.
select t1.* from table1 t1
left join table t2 on t2.id = t1.id and t2.column2 = t1.column2
I tried the below HQL query, but got an exception "unexpected token: with"
select t1 from Table1 t1
left join t1.Table2 t2 with t2.column 2 = t1.column2
There is no need to use ON statement on (LEFT or any other) JOIN. That condition will be injected by mapping. There is the HQL doc:
14.3. Associations and joins
So, this HQL will work:
SELECT t1 from Entity1 AS t1
LEFT JOIN t1.ReferencePropertyToEntity2 t2
and the generated sql will be like this:
SELECT t1 from Table1 AS t1
LEFT JOIN Table2 t2
ON t1.ReferenceColumnToTable2 = t2.Table2_ID
But in case, that we want to do more restrictions, we can extend ON clause with more conditions - but they will be all applied with AND
SELECT t1 from Entity1 AS t1
LEFT JOIN t1.ReferencePropertyToEntity2 t2
WITH t2.IsActive = 1
OR t1.IsDeleted = 0
will result in
SELECT t1 from Table1 AS t1
LEFT JOIN Table2 t2
ON t1.ReferenceColumnToTable2 = t2.Table2_ID
AND (
t2.IsActive = 1 OR t1.IsDeleted = 0
)
So, in case that we want to use WITH to totally replace ON generated by mapping, we have to go different way - with CROSS JOIN:
NHibernate HQL Inner Join (SQL Server,Visual C#)
How to join Two tables of two non relashinship defined columns using Nhibernate QueryOver

Entity framework join table against a query

I am using Entity Framework 6.1.1 and I have a query that joins a table against another select statement:
SELECT *
FROM Table1 T1
LEFT OUTER JOIN (SELECT * FROM Table2 WHERE Field = 123) AS T2 ON T1.Field = T2.Field
Is it possible to write something like this using Entity Framework's query syntax?
from t1 in Table1
join t2 in Table2.Where(t => t.Field == 123) on t1.Field equals t2.Field into t2j
select new {
T1 = t1,
T2 = t2j.DefaultIfEmpty(),
}
You can filter Table2 before the join and then use the group join + DefaultIfEmpty from https://msdn.microsoft.com/en-us/library/bb397895.aspx:
You can use LINQ to perform a left outer join by calling the DefaultIfEmpty method on the results of a group join.

SQL: Select and Inner Join three tables in one query

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;

SQL Joining three tables and using LEFT OUTER JOIN

I have three tables and two seperate SQL queries which are working correctly and I am having correct results.
If I try to join these three tables I am having null as result.
First query:
select T1.ID,T3.COMPANY
from T1,T3
where (T1.status!='CLOSED') and (T1.PRIORITY)>5 and T1.CLASSID=T3.CLASSID
Second query:
SELECT T1.ID, T2.DESCRIPTION
FROM T1
LEFT OUTER JOIN T2
ON T1.ID=T2.KEY
WHERE T1.status!='CLOSED'
AND (T2.CREATEDATE= (SELECT MAX(CREATEDATE)
FROM T2
WHERE T2.KEY=T1.ID))
I tried to join them but as result I am having null:
select T1.ID,T3.COMPANY,T2.DESCRIPTION
from T1
INNER JOIN T3 ON T1.CLASSID=T3.CLASSID
LEFT OUTER JOIN T2
ON T1.ID=T2.KEY
where (T1.status!='CLOSED') AND (T1.PRIORITY)>5
AND (T2.CREATEDATE= (SELECT MAX(CREATEDATE)
FROM T2
WHERE T2.KEY=T1.ID))
like it does not recognized last part for taking MAX value from T2 table.
What am I doing wrong? Thanks for help
Firstly, use an alias for the subquery on table T2.
T2.CREATEDATE =
(SELECT MAX(T2Alias.CREATEDATE)
FROM T2 AS T2Alias
WHERE T2Alias.KEY = T1.ID)
Secondly, consider moving this condition into the ON clause of the LEFT JOIN to table T2.
The first thing that jumps out at me is the new dependency on both T1.Priority > 5 and T2.CreateDate value being equal to the result of the inline query:
( AND (T1.PRIORITY) > 5
AND (T2.CREATEDATE =
(SELECT MAX(CREATEDATE) FROM T2 WHERE T2.KEY = T1.ID) )
Without the data it's difficult to check however this may be the issue