joining three tables between each other - sql

Is it possible to join three tables in this way .
select T1.[...],T2.[...],T3.[...]
from T1
full outer join T2 on T1.[key]=T2.[key]
full outer join T3 on T1.[key]=T3.[key]
full outer join T2 on T2.[key]=T3.[key]
My question is : Is this a valid Form?
And if no is there a way to do such operation?

It is "valid" but the full joins are not correct. The on conditions will change them to some other type of join.
Your query has other errors. But I speculate that you want:
select T1.[...], T2.[...], T3.[...]
from T1 full join
T2
on T2.[key] = T1.[key] full join
T3 join
on T3.[key] = coalesce(T2.[key], T1.[key]);

It is possible to join three tables, and your example could run with some changes, but you have syntax and scoping errors in the FROM clause.
Even those aside, I don't think it will do what you intend it to do. You'll probably want to use GROUP BY
See the examples / discussion here :
Multiple FULL OUTER JOIN on multiple tables
I also used this site as a source, as its been a while since I've touched SQL, it may be helpful to you also :
https://learnsql.com/blog/how-to-join-3-tables-or-more-in-sql/

Related

There are a few questions about the select statement

I have a few questions about the select statement.
First of all, I have normalized 15 tables for this select query.
The problem is invisible because there is not much data right now.
However, since I try to process many tables in one select query, it seems to cause problems later.
So I want to add a few more select statements to divide the tables to search, but I want to know how different it is from doing it at once.
Secondly, if I use join, I will use outer join. If I join multiple tables with outer join, I'm not sure how to use left outer join and right outer join.
The currently created select query refers to 8 tables and one join is linked.
That is, the remaining rest of the tables have obtained data in subqueries and the remaining eight tables are likely to use join.
I would appreciate it if you could let me know the direction of the multiple outer joins.
Let me briefly show you some of the current select queries.
select
a.cal1,a.cal2,a.cal3,...,
(select b.cal1 from b
where a.cal4=b.cal2)
as "bcals",
(select c.cal1 from c
where a.cal5=c.cal2)
as "ccals",
....,
(select e.cal1 from e
where a.caln=e.cal2)
as "ecals",
(select sum(extract(year from age(f.endday,f.startday))
from f
where e.cal1=a.cal1)
as "fcals",
g.cal1,g.cal2,g.cal3,...,
(select h.cal1 from h
where g.cal4=h.cal2)
as "hcals"
from a left outer join g on a.cal1=g.cal5
where a.cal1=?;
Result:
a.cal1|a.cal2|a.cal3|...|hcals
var1 |var2 |var3 |...|varn
After this, I wonder how to join the rest of the tables.
To sum up
If there are many tables that need to be included in a select query statement, what is the difference between performance and performance when this complex query is divided into multiple select statements?
If we write inside a select statement, how should outer join be?
Is there a problem with the query?
Actually your code is correct, but it looks very complex. People will find it difficult to understand it. Using joins you can minimize the lines of code and also make it more readable.
SELECT
TBL1.AMOUNT T1,
TBL2.AMOUNT T2,
TBL3.AMOUNT T3
FROM TBL1
LEFT JOIN TBL2 ON TBL2.ID = TBL1.ID
LEFT JOIN TBL3 ON TBL3.ID = TBL1.ID
In the above code , there are three tables, and two joins. One can easily understand and debug/make changes. Please try this for your code.

Why join pruning is not there in Google-BigQuery?

I'm new to BigQuery.
Tried one SQL(with standard SQL) in BigQuery which is basically like:
select T1.C1,T1.C2
from T1 left outer join T2
on T1.C1 = T2.C3
For other RDMS as I know, a join pruning will happen, which means the left outer join will not happen at execution time, since no result field/column is from T2 (right side of the left outer join).
However, in BigQuery, based on execution details of query history, the left outer join always happens, no matter result set contains fields from right side or not.
Could anyone suggest if BigQuery is designed like this?
Any way to avoid the join when no field selected from right side?
Thanks!
Matt

which way is better performance (select nested tables or join)? [duplicate]

This question already has answers here:
Explicit vs implicit SQL joins
(12 answers)
Closed 9 years ago.
SELECT * FROM dbo.table1,
dbo.table2 AS T2,
dbo.table3 AS T3,
dbo.table4 AS T4
WHERE dbo.table1.ID = T2.ID
AND T2.ID = T3.ID
AND T3.ID = T4.ID
(OR)
SELECT
*
FROM dbo.table1 T1
INNER JOIN dbo.table2 T2 ON T1.ID = T2.ID
INNER JOIN dbo.table3 T3 ON T2.ID = T3.ID
INNER JOIN dbo.table4 T4 ON T3.ID = T4.ID
Both have no difference.It is better to stay away from “comma joins” because a) the ANSI join syntax is more expressive and you’re going to use it anyway for LEFT JOIN, and mixing styles is asking for trouble, so you might as well just use one style; b) ANSI style is clearer.
Both will take same time to execute, there is no performance difference .
Without Join keyword it behave as Cross Joins, produce results that consist of every combination of rows from two or more tables. That means if table table2 has 6 rows and table table3 has 3 rows, a cross join will result in 18 rows. There is no relationship established between the two tables – you literally just produce every possible combination.
With an inner join, column values from one row of a table are combined with column values from another row of another (or the same) table to form a single row of data.
If a WHERE clause is added to a cross join, it behaves as an inner join as the WHERE imposes a limiting factor.
In both the cases you mentioned above, there wont be any difference in the way sql engine executes them in the background. The only thing affects on performance is how effective are your indexes on joining columns in case of join and where clause in case of comma separated tables names.
So just make sure you have proper indexes,statistics updated etc
And one more important thing is you are using select "*", if possible try to use only the columns you are interested.
Both are joins, first is implicit, which will perform cross join as pointed in previous answer, the latter one is an explicit inner join notion. Though it should not make a difference in terms of performance.

SQL JOIN where to place the WHERE condition?

I have two following examples.
1. Example (WHERE)
SELECT 1
FROM table1 t1
JOIN table2 t2 ON t1.id = t2.id
WHERE t2.field = true
2. Example (JOIN AND)
SELECT 1
FROM table1 t1
JOIN table2 t2 ON t1.id = t2.id AND t2.field = true
What is the faster way in terms of performance? What do you prefer?
If a filter enters in a JOIN condition functionally (i.e. it is an actual join condition, not just a filter), it must appear in the ON clause of that join.
Worth noting:
If you place it in the WHERE clause instead, the performances are the same if the join is INNER, otherwise it differs. As mentioned in the comments it does not really matter since anyway the outcome is different.
Placing the filter in the WHERE clause when it really is an OUTER JOIN condition implicitely cancels the OUTER nature of the condition ("join even when there are no records") as these filters imply there must be existing records in the first place. Example:
... table1 t LEFT JOIN table2 u ON ... AND t2.column = 5 is correct
... table1 t LEFT JOIN table2 u ON ...
WHERE t2.column = 5
is incorrect, as t2.column = 5 tells the engine that records from t2 are expected, which goes against the outer join. Exception to this would be an IS NULL filter, such as WHERE t2.column IS (NOT) NULL (which is in fact a convenient way to build conditional outer joins)
LEFT and RIGHT joins are implicitely OUTER joins.
Hope it helped.
JOIN conditions should normally be independent from filter conditions. You define rules of your join (the how) with ON. You filter what you want with WHERE. Performance wise, there's no general rule across all engines and designs, so your mileage will vary greatly.
I think the faster way is to put the filter in the where clause, because it will procees that filter in the where first , and then the join clause, so there will be no need of permutation of filters.

NESTED INNER JOIN using MS Access 2003 via ODBC

If this works:
SELECT COUNT(t1.ID) AS count FROM Project t1
INNER JOIN (SELECT DISTINCT t.Site,t.id FROM _Equipment_id t WHERE t.OEM LIKE '%ABC%') t2 ON t1.Site=t2.Site AND t1.id=t2.id
and this works:
SELECT COUNT(t3.ID) AS count FROM Wall t3
INNER JOIN Project t1 ON t3.Project_number=t1.Project_number
Why doesn't this work:
SELECT COUNT(t3.ID) AS count FROM Wall t3
INNER JOIN Project t1 ON t3.Project_number=t1.Project_number
INNER JOIN (SELECT DISTINCT t.Site,t.id FROM _Equipment_id t WHERE t.OEM LIKE '%ABC%') t2 ON t1.Site=t2.Site AND t1.id=t2.id
Ultimately, I have 10 tables like the Wall table that I am trying to get a total count from the first SELECT....
SELECT COUNT(t3.ID) AS count FROM Wall t3
INNER JOIN (Project t1
INNER JOIN (SELECT DISTINCT t.Site,t.id FROM _Equipment_id t WHERE t.OEM LIKE '%ABC%') t2
ON t1.Site=t2.Site AND t1.id=t2.id)
ON t3.Project_number=t1.Project_number
Maybe it's just a syntax error? Office Help at the bottom where they mention nesting. The other possibility is that the aliases are somehow scoped so that they are not available to the join, but I'm no expert on MS Access. Maybe you should just try dropping the aliases altogether.
You have a couple of minor issues with your code: a table name that starts with an underscore character (_Equipment_id) and an AS clause ("alias") that is a SQL keyword (AS count). When these are corrected, your SQL is valid SQL-92 syntax.
Sadly, the problem is that Access (ACE, Jet, whatever) does not support the SQL-92 Standard. Access insists that each nested JOIN clause is put in parentheses.
[Aside: JOINs in parentheses are allowed in Standard SQL because it can potentially change the query results. However Access, does not respect the order specified by the coder and allows itself to evaluate JOINs in order it sees fir. So not only Access's syntax non-compliant with the Standard, there is also a loss of functionality! However, this further problem with Access will have no ill effect for this particular query.]
You have two JOINs in the same scope here:
...
INNER JOIN Project t1 ON t3.Project_number=t1.Project_number
INNER JOIN
...
Your code needs to work around Access's problem by enclosing the JOIN in parentheses; because all your JOINs are INNER flavour, it probably doesn't matter where they go.
Also, as regards correcting your AS clause, Access again doesn't support Standard SQL's quoted identifiers (...AS "count"...) and insists you use its proprietary square brackets syntax (...AS [count]...) -- of course, you could choose a different name but there may exist application code that relies on it.
Code to workaround both Access problems:
SELECT COUNT(t3.ID) AS [count]
FROM (Wall t3
INNER JOIN Project AS t1
ON t3.Project_number = t1.Project_number)
INNER JOIN (
SELECT DISTINCT t.Site,t.id
FROM _Equipment_id AS t
WHERE t.OEM LIKE '%ABC%'
) AS t2
ON t1.Site = t2.Site
AND t1.id = t2.id;