NESTED INNER JOIN using MS Access 2003 via ODBC - sql

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;

Related

joining three tables between each other

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/

What's the scope of table aliases?

This question is in the context of Sqlite but I wonder in general what's the rule for aliases. Suppose I have the following query:
SELECT *
FROM (SELECT * FROM tableA as t1 inner join tableB as t2 on t1.id=t2.some_id) as t3,
(SELECT * FROM tableC as t1 inner join tableD as t2 on t1.id=t2.some_id) as t4
WHERE t3.id=t4.id
The question is, will the two t1's and t2's clash? in my experience with multiple database vendors they won't clash, but, could it confuse the optimizer to the point of producing a buggy result? I have this hypothesis for a query giving bogus results in Sqlite.
No, the aliases will not clash. They are known only in their respective subqueries.
Of course, the query will fail because of the trailing comma. And in general, you should avoid commas in the FROM clause. Always use proper, explicit, standard, readable JOIN syntax.

SQL Server inner join vs MS Access inner join

I have to convert an Access query to Sql Server query.
In my FROM clause I have something like this:
FROM
(table1 INNER JOIN table2 ON table1.afield = table2.afield)
I'm think that my FROM clause in Sql Server should remain unchanged but I'm not sure about that.
Can you please give me confirm about that?
You can use what you have, I'd take out the parenthesis though;
FROM table1
INNER JOIN table2
ON table1.afield = table2.afield
It would also be a good idea to get into the habit of using table aliases too, something like this;
FROM table1 AS t1
INNER JOIN table2 AS t2
ON t1.afield = t2.afield
As this will help the readability of the code.

What Does *= means in WHERE Clause in TSQL?

some one have asked me the output of below query.
Select *
from TableA t1, TableB t2
where t1.Id *= t2.Id
Can anyone explain me, if such type of any query exists, if so then how its works. Because i have never seen such type of query Thanks.
UPDATE:
Also when i run this query in SQL Server, i get this;
The query uses non-ANSI outer join operators ("*=" or "=*").
To run this query without modification, please set the compatibility level
for current database to 80, using the SET COMPATIBILITY_LEVEL option
of ALTER DATABASE.
It is strongly recommended to rewrite the query using ANSI outer join
operators (LEFT OUTER JOIN, RIGHT OUTER JOIN).
In the future versions of SQL Server, non-ANSI join operators will
not be supported even in backward-compatibility modes.
Using asterisk in a WHERE is an old non-ANSI compliant syntax for OUTER JOINing tables and therefore should not be used anymore.
Here's the link.
The asterisk in the where condition is actually part of a non-ANSI outer join operator, it is used to define an implicit outer join.
It will cause trouble in modern databases as this operator has been obsolete since 1992.
Essentially the below are the same:
SELECT * FROM TableA LEFT OUTER JOIN TableB ON t1.Id = t2.Id
SELECT * FROM TableA , TableB WHERE t1.Name *= t2.Name
The *= operator means LEFT OUTER JOIN.

Select from 2 tables with a left join

Here is probably an easy one if your used to SQL, which I'm not.
I have this query:
SELECT *
FROM myTable
LEFT JOIN anotherTable
ON myTable.myField=anotherTable.anotherField
Actually, this query returns everything from myTable which meets the join condition (as far as my comprehension goes). This query works great, but I would like to select another field from another table. What I would like to do is something like this:
SELECT myTable.*, myTable2.aSpecificField
FROM myTable, myTable2
LEFT JOIN anotherTable
ON myTable.myField=anotherTable.anotherField
WHERE myTable.id = myTable2.id
However, this doesn't work, I get an error message about the LEFT JOIN. I would like the aSpecificField from myTable2 to be added to the rows where the ID of both tables match.
Can you help me building this query correctly? Thank you.
The Microsoft Access query design window lets you use wizards or drag-and-drop to create queries. You can then tidy up the SQL in design view. Add your tables to the design grid, drag the joining fields from one table to the next, and then select the fields you want.
When you wish to advance your knowledge of Access SQL, you can read ...
These are for Jet (<2007), but ACE (>=2007) is not that different as regards SQL
Fundamental Microsoft Jet SQL for Access 2000
Intermediate Microsoft Jet SQL for Access 2000
Advanced Microsoft Jet SQL for Access 2000
Jet Database Engine
Background on design
Fundamentals of Relational Database Design, Paul Litwin, 2003
An often recommended MS Access book
Access cookbook
List out your fields rather then using *. Like so:
SELECT m.Field1, m.Field2, m2.Field1 FROM
MyTable m LEFT JOIN MyTable2 m2 ON m2.ID=m1.ID
Per your comment what relation does table3 have with another table?
Just include it based on that relationship
SELECT m.Field1, m.Field2, m2.Field1, m3.Field1 FROM
MyTable m LEFT JOIN MyTable2 m2 ON m2.ID=m1.ID LEFT JOIN MyTable3 m3 ON m3.ID=m2.ID
So you want to return the rows where the ids match for both tables? And not where they dont match? So not a left or right join but a plain join?
Select tab1.*,tab2.* from mytable tab1
INNER JOIN mytable2 tab2
ON tab1.id = tab2.otherid
Or if you have 3 tables to join?
Select tab1.*,tab2.*,tab3.* from mytable tab1
INNER JOIN mytable2 tab2
ON tab1.id = tab2.otherid
INNER JOIN mytable3 tab3
ON tab1.id = tab3.anotherid
Replace tabX.* with specific fields if needed?