ORA 00936 error while using left outer join + syntax - sql

I have two tables: T1 and T2
T1 has a DATE column: CT1
T2 has a DATE column: CT2
I want to left outer join T1 and T2 with join condition:
trunc(CT1,'Mi')=trunc(CT2,'Mi')(+)
When I try to run this SQL, I receive error ORA 00936:missing expression.
Any idea what is wrong here?

I think that you need to put the (+) operator immediately after the column name that it applies to.
trunc(CT1,'Mi')=trunc(CT2 (+),'Mi')
"The (+) operator can be applied only to a column, not to an arbitrary expression. However, an arbitrary expression can contain one or more columns marked with the (+) operator." (from http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/queries006.htm)
In any case, I would suggest using the ANSI syntax. It's clearer, more functional, and portable.

Try using ANSI syntax:
T1 LEFT OUTER JOIN T2 ON TRUNC(CT1,'Mi')=TRUNC(CT2,'Mi')
The (+) outer join syntax has some limitations, this could be one of them. Of course, if you change this join, you'll have to change them all - you can't mix the two.

Related

Are these SQL queries equivalent [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Explicit vs implicit SQL joins
Is there a difference using join andselect from multi-tables?
SQL Joins: Future of the SQL ANSI Standard (where vs join)?
What is the difference between JOIN and declaring multiple tables in the FROM clause?
Such as:
SELECT *
FROM table1 AS t1,
table2 AS t2
WHERE t1.id = t2.id
Compared to:
SELECT *
FROM table1 AS t1
INNER JOIN table2 AS t2 ON t2.id = t1.id
The second version, with the explicit JOIN and join condition is standardized SQL.
The implicit join syntax with a WHERE clause is deprecated syntax (or, rather, considered bad) - partially because it is easy to forget the WHERE clause and cause a Cartesian product.
Why Use the new syntax?
As others have stated, the new syntax has become the preferred convention. In larger queries the new syntax is easier to read, debug, and ensure the join criteria is added (meaning no accidental CROSS JOINS.
Is the old syntax deprecated (for inner joins)?
Not according to ANSI -- both are valid, even if the first is disfavored. Although, performing outer joins in the old syntax has been deprecated -- mainly because it can be ambiguous.
How consensus is the "use the new syntax" view ?
Aaron Bertran considers it a "bad habit to kick"
SQL Server Central the consensus was "Kill kill kill it with fire"
Joe Celko -- meh, but it's easier to read.
Both will output the same and are just different variations of writing the query.
SELECT *
FROM table1 AS t1
INNER JOIN table2 AS t2 ON t2.id = t1.id
Is the preferred join method as you are explicitly stating which type of join you are using, i.e. LEFT, OUTER, INNER.

SQL Left Outer Join causes Msg 4145 (non-boolean where boolean expected)

I'm new here so if I do something that breaks convention please let me know.
I am trying to create a simple query that includes a single outer join before I move onto a larger and more complicated query. When I run my query before adding the join it works as expected. When I add the join the query returns an error message. I cannot determine the cause of the error. I am working in Microsoft SQL Server 2008 R2.
This query runs successfully and produces the expected results:
use MyDatabase
select table1.ID_NUM,
table1.LAST_NAME
From table1,
table2
where table1.id_num = table2.id_num
This query does not run successfully:
use MyDatabase
select table1.ID_NUM,
table1.LAST_NAME
From table1,
table2
where table1 left outer join table2 on table1.id_num = table2.id_num
The error message I get is:
Msg 4145, Level 15, State 1, Line 6
An expression of non-boolean type specified in a context where a condition is expected, near 'left'.
I also tried "outer join" instead of "left outer join", but this produced a similar error message (the only difference was "near 'outer'" instead of "near 'left'").
I do know what boolean means but I am not sure why it's an issue here. The boolean operator comes later in the same line. My code looks like it follows the same format as other code I have seen. Any assistance would be appreciated.
your join needs to be after the FROM not in the WHERE clause
use MyDatabase
select table1.ID_NUM,
table1.LAST_NAME
From table1
left outer join table2 on table1.id_num = table2.id_num
You are using deprecated syntax, listing out tables and defining their relationship in the WHERE clause has been replaced by explicit JOIN statements
FROM Table1 t1
JOIN Table2 t2
ON t1.col1 = t2.col1
LEFT JOIN Table3 t3
ON t1.col2 = t3.col1
Old style joins do allow for outer joins:
use MyDatabase
select table1.ID_NUM,
table1.LAST_NAME
From table1,table2
where table1.id_num *= table2.id_num
This old syntax should be avoided, but helpful to know what they are if you come across them.

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.

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;

What does =* mean?

I'm trying to trace some SQL in Microsoft Server. I came across a join that is using a convention unfamiliar to me. What does "=*" mean?
WHERE table1.yr =* table2.yr -1
This:
WHERE t.column =* s.column
...is old TSQL (pre SQL Server 2005) outer join syntax, and is not an ANSI JOIN.
Reference: SQL Server 2005 Outer Join Gotcha
I believe that is old syntax indicating an outer join condition from table1 to table2
Old style:
SELECT * FROM table1, table2
WHERE table1.yr =* table2.yr -1
New style (SQL92):
SELECT * FROM table2
LEFT OUTER JOIN table1 ON table1.yr = table2.yr - 1
This is the old style syntax for expressing joins
It means the code needs to be replaced immediately! This style join is supposed to be a right join. Unfortunately it will sometimes be interpreted as a cross join, so the results of using this join may not be correct. Also, this syntax is deprecated and cannot be used inteh next version of SQl server.
That is the ANSI SQL 1989 syntax for RIGHT OUTER JOIN, where *= would be the LEFT OUTER JOIN.
You should note also that putting the join syntax in the WHERE clause is deprecated in SQL 2008. http://scarydba.wordpress.com/2009/09/15/no-join-predicate/ <== A timely article on this.
This is the old style of joins which were deprecated in ANSI SQL92. New syntax uses INNER and OUTER JOIN which join tables based on expressions rather than equality
A ??? outer join is specified using the symbol =* in place of = in the WHERE clause.
yeap, it's another syntax for a left outer join
from
table1 left outer join table2 on table1.yr = table2.yr - 1
SELECT *
FROM table1, table2
WHERE table1.yr =* table2.yr -1
Means the same thing as this:
SELECT *
FROM
table2
LEFT OUTER JOIN
table1
ON table1.yr = (table2.yr - 1)
The * syntax is considered outdated, and is not in line with the ANSI standards.
Oracle has a similar construct like this:
WHERE table1.yr (+)= table2.yr
To be plain and simple.
This is a SQL-92 outer join operator ( more info )
Don't use it, its very old school, but its similar to LEFT JOIN, and RIGHT JOIN.
All its doing is telling which side of the join is the "Parent" side, so rows on that side will be considered first.
If you try to run this on SQL 2005, it will throw an error, saying that you need to run this in compatibility mode.
There are a lot of silly answers here. You didn't give the FROM clause, so there's no way to tell if your *= represents a LEFT or a RIGHT outer join.
WHERE table1.yr =* table2.yr -1
is old syntax for an outer join, for sure. But anyone who claims to know whether it's a LEFT or RIGHT outer join is mistaken. It depends on the order in which table1 and table2 are named in the FROM clause, and that's not given.