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.
Related
Below is a join based on where clause:
SELECT a.* FROM TEST_TABLE1 a,TEST_TABLE2 b,TEST_TABLE3 c
WHERE a.COL11 = b.COL11
AND b.COL12 = c.COL12
AND a.COL3 = c.COL13;
I have been learning SQL from online resources and trying to convert it with joins
Two issues:
The original query is confusing. The outer joins (with the (+) suffix) are made irrelevant by the last where condition. Because of that condition, the query should only return records where there is an actual matching c record. So the original query is the same as if there were no such (+) suffixes.
Your query joins TEST_TABLE3 twice, while the first query only joins it once, and there are two conditions that determine how it is joined there. You should not split those conditions over two separate joins.
BTW, it is surprising that the SQL Fiddle site does not show an error, as it makes no sense to use the same alias twice. See for example how MySQL returns the error with the same query on dbfiddle (on all available versions of MySQL):
Not unique table/alias: 'C'
So to get the same result using the standard join notation, all joins should be inner joins:
SELECT *
FROM TEST_TABLE1 A
INNER JOIN TEST_TABLE2 B
ON A.COL11 = B.COL11
INNER JOIN TEST_TABLE3 C
ON A.COL11 = B.COL11
AND B.COL12 = C.COL12;
#tricot correctly pointed out that it's strange to have 2 aliases with the same name and not getting an error. Also, to answer your question :
In the first query, we are firstly performing cross join between all the 3 tables by specifying all the table names. After that, we are filtering the rows using the condition specified in the WHERE clause on output that we got after performing cross join.
In second query, you need to join test_table3 only once. Since now you have all the required aliases A,B,C as in the first query so you can specify 2 conditions after the last join as below:
SELECT A.* FROM TEST_TABLE1 A
LEFT JOIN TEST_TABLE2 B
ON A.COL11 = B.COL11
left join TEST_TABLE3 C
on B.COL12 =C.COL12 AND A.COL3 = C.COL13;
I am using AWS Redshift SQL. I want to inner join a sub-query which has group by and inner join inside of it. When I do an outside join; I am getting an error that column does not exist.
Query:
SELECT si.package_weight
FROM "packageproduct" ub "clearpathpin" cp ON ub.cpipr_number = cp.pin_number
INNER JOIN "clearpathpin" cp ON ub.cpipr_number = cp.pin_number
INNER JOIN (
SELECT sf."AWB", SUM(up."weight") AS package_weight
FROM "productweight" up ON up."product_id" = sf."item_id"
GROUP BY sf."AWB"
HAVING sf."AWB" IS NOT NULL
) AS si ON si.item_id = ub.order_item_id
LIMIT 100;
Result:
ERROR: column si.item_id does not exist
It's simply because column si.item_id does not exist
Include item_id in the select statement for the table productweight
and it should work.
There are many things wrong with this query.
For your subquery, you have an ON statement, but it is not joining:
FROM "productweight" up ON up."product_id" = sf."item_id"
When you join the results of this subquery, you are referencing a field that does not exist within the subquery:
SELECT sf."AWB", SUM(up."weight") AS package_weight
...
) AS si ON si.item_id = ub.order_item_id
You should imagine the subquery as creating a new, separate, briefly-existing table. The outer query than joins that temporary table to the rest of the query. So anything not explicitly resulted in the subquery will not be available to the outer query.
I would recommend when developing you write and run the subquery on its own first. Only after it returns the results you expect (no errors, appropriate columns, etc) then you can copy/paste it in as a subquery and start developing the main query.
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.
Have tried the below SQL in MS Access but cannot seem to get it working, anyone got a better idea?
SELECT top 4 Student.STUDENT_DEGREE, Student.STUDENT_SEX,STUDENT_GROUP_ID,STUDENT_GROUP_ID2,RESULT_MARK
FROM (((Student)
INNER JOIN Result ON Student.STUDENT_ID=Result.RESULT_STUDENT_ID)
INNER JOIN Group ON RESULT_GROUP_ID = GROUP_ID)
where STUDENT_GROUP_ID <> ''
order by Result.RESULT_MARK desc;
Whenever i run this i just get the error:
Syntax error in FROM clause
Group is a reserved word. Enclose that name in square brackets to avoid confusing the db engine. You can also assign an alias for the table name.
FROM
(Student
INNER JOIN Result
ON Student.STUDENT_ID=Result.RESULT_STUDENT_ID)
INNER JOIN [Group] AS g
ON Result.RESULT_GROUP_ID = g.GROUP_ID
I had to guess which tables contain those fields in the last ON clause. If you set up the joins in Design View of the Access query designer, it will help you get the names right. It will also add the parentheses which the db engine requires for any query which includes more than one join.
Also qualify the table sources for the field names in your SELECT list and elsewhere in the query. Here again, the query designer can supply the correct names for you.
Remove the extra set of parentheses around Student:
SELECT top 4 Student.STUDENT_DEGREE,Student.STUDENT_SEX,STUDENT_GROUP_ID,STUDENT_GROUP_ID2,RESULT_MARK
FROM ((Student
INNER JOIN Result ON Student.STUDENT_ID=Result.RESULT_STUDENT_ID)
INNER JOIN Group ON RESULT_GROUP_ID = GROUP_ID)
where STUDENT_GROUP_ID <> ''
order by Result.RESULT_MARK desc;
I have the following SQL:
SELECT * FROM Name
INNER JOIN ( SELECT 2 AS item, NameInAddress.NameID as itemID, NameInAddress.AddressID
FROM NameInAddress
INNER JOIN Address ON Address.AddressID = NameInAddress.AddressID
WHERE (Address.Country != 'UK')
) AS Items ON (Items.itemID = Name .Name ID)
I have been asked to remove the nested select and use INNER JOINS instead, as it will improve performance, but I'm struggling.
Using SQL Server 2008
Can anyone help?
Thanks!
Your query is not correct as you're using Items.itemID while it's not in the subselect
I guess this is what you meant:
SELECT Name.*
FROM Name
INNER JOIN NameInAddress
ON Name.NameID = NameInAddress.NameID
INNER JOIN Address
ON Address.AddressID = NameInAddress.AddressID
WHERE (Address.Country != 'UK')
EDIT: The exact translation of your query would start with a SELECT Name.*, 2 as Item, NameInAddress.NameID, NameInAddress.AddressID though
It is one of those long-lived myths that nested selects are slower than joins. It depends completely on what the nested select says. SQL is just a declarative language to tell what you want done, the database will transform it into completely different things. Both MSSQL and Oracle (and I suspect other major engines as well) are perfectly able to transform correlated subqueries and nested views into joins if it is beneficial (unless you do really complex things which would be very hard, if possible, to describe with normal joins.
SELECT 2 AS Item, *
FROM Name
INNER JOIN NameInAddress
ON Name.NameID = NameInAddress.NameID
INNER JOIN Address
ON Address.AddressID = NameInAddress.AddressID
WHERE Address.Country != 'UK'
PS: Don't use "*". This will increase performance too. :)