SQL syntax: outer table_name - sql

I have a project with this query that I don't get something in it.
Select
c.prop_table1,
(SELECT max(t.taux_table_x) FROM DB3:table_x t
WHERE month(t.date_prop_x) = month(c.prop_of_x)
AND year(t.date_prop_x) = year(c.prop_of_x)
)*1 table_x,
''||date(c.prop_of_x) Alias
FROM DB1:table_name1 d, DB1:table_name2 c, outer DB2:table_name a
WHERE
c.value_i = d.value_i AND
c.property =d.property AND
(c.num_table_name2 =a.no_dos_adh OR c.ref_cred=a.no_dos_adh) AND
c.abcd not in ('P','S')
I don't know what outer is expressing exactly. Is it a left/right or full join? Or is it something else?
thanks for the help everyone

It looks a lot like your query is written using the (IBM) Informix SQL dialect. If that is the case then the outer should be a left outer join as it has a table on its left side (I believe a right join would be from outer tab1, tab2)
The syntax predates the SQL-92 standard but should still be valid (?) with Informix.
Rewritten as standard SQL it would probably look like this:
SELECT
c.prop_table1,
(
SELECT max(t.taux_table_x) FROM DB3:table_x t
WHERE month(t.date_prop_x) = month(c.prop_of_x)
AND year(t.date_prop_x) = year(c.prop_of_x)
)*1 table_x,
'' || date(c.prop_of_x) Alias
FROM
DB1:table_name1 d
INNER JOIN
DB1:table_name2 c ON c.value_i = d.value_i AND c.property = d.property
LEFT JOIN
DB2:table_name a ON (c.num_table_name2 = a.no_dos_adh OR c.ref_cred = a.no_dos_adh)
WHERE
c.abcd not in ('P','S')

I don't know what outer is expressing exactly is it a left/ right or full join?
Not withstanding syntax problems with your sql code, outer is the set union of left and right. In your example, this is the equivalent
(table1,table2) union (table3)
But your SQL is sorely incomplete to give any more specific answers.

Related

SQL Fieldname vs Aliasname

I have been trying to figure out why the following SQL works
SELECT c_Supplier.Supplier_ID AS A_ID, c_Supplier.Name, c_Supplier.RFC, c_Supplier_Direccion.Description, c_Supplier_Direccion.Address, c_Supplier_Phone.Phone
FROM c_Supplier LEFT JOIN (c_Supplier_Direccion LEFT JOIN c_Supplier_Phone ON c_Supplier_Direccion.Supplier_Direccion_ID = c_Supplier_Phone.Supplier_Direccion_ID) ON c_Supplier.Supplier_ID = c_Supplier_Direccion.Supplier_ID
WHERE (c_Supplier.Supplier_ID=1);
But when I try to use the aliasname (A_ID) in the WHERE clause, I got an error
SELECT c_Supplier.Supplier_ID AS A_ID, c_Supplier.Name, c_Supplier.RFC, c_Supplier_Direccion.Description, c_Supplier_Direccion.Address, c_Supplier_Phone.Phone
FROM c_Supplier LEFT JOIN (c_Supplier_Direccion LEFT JOIN c_Supplier_Phone ON c_Supplier_Direccion.Supplier_Direccion_ID = c_Supplier_Phone.Supplier_Direccion_ID) ON c_Supplier.Supplier_ID = c_Supplier_Direccion.Supplier_ID
WHERE (A_ID=1);
Any ideas?
I don't understand your question. This is a reasonably formed SQL query:
SELECT c_Supplier.Supplier_ID AS Entidad_ID, c_Supplier.Name,
c_Supplier.RFC, c_Supplier_Direccion.Description,
c_Supplier_Direccion.Address, c_Supplier_Phone.Phone
FROM c_Supplier LEFT JOIN
(c_Supplier_Direccion LEFT JOIN
c_Supplier_Phone
ON c_Supplier_Direccion.Supplier_Direccion_ID = c_Supplier_Phone.Supplier_Direccion_ID
) ON c_Supplier.Supplier_ID = c_Supplier_Direccion.Supplier_ID
WHERE (c_Supplier.Supplier_ID = 1);
(I would recommend table aliases for readability, but that is a separate issue.)
It has no alias called A_ID anywhere in the query, so there is no reason to ever expect a reference to A_ID to work (unless it is a column in one of the tables).
And, SQL doesn't allow the re-use of table aliases in the SELECT where they are defined or the WHERE clause. This is not an MS Access limitation; it is how the SQL language is defined.
If you want to do so in MS Access, you can use a subquery and reference the table alias in the outer query.

Join expression not supported SQL

SELECT
Trs.itemID, Trs.imtName, Trs.sumQty, Sum(whiQty)
FROM
((SELECT
trsitemID AS itemID, trsimtName AS imtName,
Sum(trsQty) As sumQty
FROM
tblTransactionSub AS T
WHERE
trstraID = 1231
AND trsActive = True
GROUP BY
trsitemID, trsimtName) AS Trs
INNER JOIN
tblWarehouseItem AS WHI ON Trs.itemID = WHI.whiitemID)
RIGHT JOIN
WHI ON Trs.trswhiID = WHI.whiID
WHERE
whiActive = True
AND whiCansel = False
AND whiwrhID = 19
GROUP BY
Trs.itemID,Trs.imtName, Trs.sumQty
HAVING
SUM(whiQty) < Trs.sumQty
If you please help me me out since I am new to SQL commands I can not easily find my mistake.
Thanks in advance
The error that occurred when I added the Right Join is:
Join expression not supported
In MS Access, you have to use parenthesises with multiple joins:
select ...
from
((table1
... join table2 on ...)
... join table3 on ...)
... join tableN
/edit/
As OP question changes its syntax often, then my answer seems out of place :) Initially there were no parens there.
About RIGHT JOIN: You need to use table name (or entire subselect) after JOIN keyword, not skip it or use some other alias. Your query part
RIGHT JOIN
WHI ON Trs.trswhiID = WHI.whiID
currently uses alias WHI, which is wrong in two ways: 1) it is not table name 2) it is already used. You need something like this:
RIGHT JOIN
tblWarehouseItem AS WHI2 ON Trs.trswhiID = WHI2.whiID
It could be possible that MS Access restricts your kind of JOINs usage (like INNER join should not come after LEFT join); I have currently no possibility to check precise rules.
Your problem is that you have no table name after the RIGHT JOIN:
RIGHT JOIN
ON Trs.trswhiID = WHI.whiID
Should be:
RIGHT JOIN YOURTABLENAMEHERE as alias
ON Trs.trswhiID = WHI.whiID
However, you have already defined Trs and Whi, so I have no idea what table you want there, or why. Perhaps you just want to change the INNER JOIN to a LEFT JOIN or RIGHT JOIN.

(+) symbol in SQL Query

Just i have came across a SQL query in one of the stored procedure like below:
SELECT
*
FROM
account a,
performance p,
customer c,
override o
WHERE
a.account_id = p.account_id (+)
AND a.account_id = c.account_id (+)
AND o.override_type(+) = 'O'
Can you please explain what is the (+) symbol's play here? and the difference of using Left side and right side.
Thanks in advance.
It is the old syntax for OUTER JOIN in Oracle (I don't know whether there are other RDBMS that uses the same old syntax or not).
Better off: Use the explicit ANSI-92 OUTER JOIN syntax using LEFT OUTER JOIN or RIGHT OUTER JOIN instead of the + symbol.
(+) is an legacy outer join syntax in oracle (8 and before). It is very restrictive and handles many cases just wrong. Don't use it anymore. Oracle supports ansi joins (eg. left outer join) since version 9.

What does (+) do in Oracle SQL?

I'm using Oracle SQL Developer to query an Oracle DB (not sure which version it is) and I'm going to use the SQL I make for a Crystal report. Many of the reports the previous developers have written don't use JOIN keywords to make the joins (and I'm not too familiar with JOIN keywords as a result).
Many of the joins they make are made in the WHERE statement. I'll notice something like this.
Select * From TableA, TableB WHERE TableA.PrimaryKey(+) = TableB.ForeignKey
My question is concerning the (+). What purpose does it serve and how do I use it in my code?
It is not recommended. See this previous answer
Difference between Oracle's plus (+) notation and ansi JOIN notation?
That represents a “right outer join” (right because the = is on the right side of the +).
SELECT *
FROM TableA, TableB
WHERE TableA.PrimaryKey(+) = TableB.ForeignKey
is equivalent to
SELECT *
FROM TableA
RIGHT OUTER JOIN TableB
ON (TableA.PrimaryKey = TableB.ForeignKey)
right outer join
(+) is used to perform right outer join in Oracle
RIGHT OUTER JOIN is one of the JOIN operations that allow you to specify a JOIN clause
For details
http://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqlj57522.html

Refactor SQL (workaround RIGHT OUTER JOIN)

Since SQLite does not support RIGHT OUTER JOINS I pose the following challenge (read: invitation to do my work for me):
Refactor this query so it no longer utilises SQLite-unsupported constructs like RIGHT/FULL OUTER JOINs.
SELECT strings.*, translations.text
FROM translations INNER JOIN
language ON translations.language_id = language.id RIGHT OUTER JOIN
strings ON translations.string_id = strings.id
WHERE (language.handle = 'english')
I sense it can be achieved with subqueries or by pivoting the tables and performing a LEFT OUTER JOIN but my attempts have failed; my SQL's not what it used to be.
Here's a query builder outline showing the applicable schema: http://dl.getdropbox.com/u/264612/sql-refactor.PNG
First to crack it gets an e-hug from dekz
The following is untested.
select strings.*, translations.text
from strings left outer join translations
on translations.string_id = strings.id
and translations.language_id = (select id
from language
where language.handle = 'english')
I think this will give you all strings with the matching translation text where a suitable translation exists in English. Is that what you are trying to get?
Intriguing that SQLite allows LEFT OUTER JOINs but not RIGHT OUTER JOINs. Well, since it does allow LEFT OUTER JOINs, you're right, you can just rearrange the join order:
SELECT strings.*, translations.text
FROM strings LEFT OUTER JOIN (
translations INNER JOIN language ON translations.language_id = language.id
) tr ON tr.string_id = strings.id
WHERE (language.handle = 'english')
[EDIT: Applied Blorgbeard's suggestion of naming the joined table to get the query to parse -- hope it works now!]