I get a Syntax error: missing 'closing parenthesis' when I add a specifier to my USING statement
Here is an example similar to what I am doing:
SELECT * FROM student s JOIN test_result using (s.id) where s.id = 1335;
My actual query is much more complex, I have multiple tables that I want to join and some tables have columns with the same name so when I try to JOIN one of those tables with a third table, I get a Error Code: 1052. Column 's.id' in from clause is ambiguous. When I try to avoid that by specifying which table's id I want to use I get a Syntax error: missing 'closing parenthesis'
The column(s) within the USING() clause do not take aliases - the base idea is that this column should be available in both tables.
This also has the advantage of disambiguating the column, so you don't event need to prefix it with a table alias in the WHERE claus.
Just:
SELECT *
FROM student s
INNER JOIN test_result ts USING (id)
WHERE id = 1335;
The downside is that, if you use that in a multi-join context where several tables have an id column, you don't get to choose from which table id is picked. This can be troublesome in some situations. In that case, you need to switch back to the join ... on ... syntax:
SELECT *
FROM student s
INNER JOIN test_result ts on ts.id = s.id
WHERE id = 1335;
Reading your comment, I think you need an alias based join
SELECT *
FROM student s
JOIN test_result t ON t.id = s.id
where s.id = 1335;
Related
SELECT Sub_Genre.sgid, Sub_Genre.sgname, Region.rname
FROM Sub_Genre AS S, Region AS R
JOIN Band_Styles AS bSty ON bSty.sgname=S.sgname
JOIN Band_Origins AS bOri ON bOri.bname=bSty.bname
JOIN Country AS C ON C.cname=bOri.cname
JOIN Region ON R.rname=C.rname
ORDER BY S.sgid;
I am trying to Create a query to determine which sub_genres come from which regions.
I keep getting an Error Code 1054. Unknown column 'Sub_Genre.sgid' in 'field list'
Don't mix explicit and implicit joins. Use standard, explicit joins consistently.
Table region appears twice in the query, first in an implicit join with an alias, and then in a standard join without an alias. This is most likely not what you want.
Columns in the select clause are prefixed with the entire table name, while the table are aliased in the from clause: this is not supported.
This would be a cleaner way to express the logic:
select s.sgid, s.sgname, r.rname
from sub_genre s
join band_styles bsty on bsty.sgname = s.sgname
join band_origins bori on bori.bname = bsty.bname
join country c on c.cname = bori.cname
join region r on r.rname = c.rname
order by s.sgid;
This fixes the syntax problems. Whether this gives the correct results or not is something else: you did not share the structures and data you are working with, so I cannot tell.
I want to join two tables together which are the run table and the restaurant table. From the run table I need the run_id and the restaurant_id and from the restaurant table, I need the created_date so in the end, I have a table that contains the created_date of each restaurant. Both the run and restaurant_history tables have run_id's so that's how I know I can join them. I came up with something like:
SELECT run_id, restaurant_id, created_date FROM restaurant_history, run
JOIN run ON restaurant_history.run_id = run.run_id;
But that gave me an error. Any help would be appreciated :)
(I'm fairly new to sql)
You are mixing both implicit joins and explicit joins. The implicit join syntax (listing the tables in the FROM clause) was deprecated over 25 years ago.
As a simple rule, never use commas in the FROM clause:
SELECT R.run_id, restaurant_id, created_date
FROM restaurant_history H
JOIN run R ON H.run_id = R.run_id;
As for why it gave you that error, error is two-fold. Let's look at what you had written:
SELECT run_id, restaurant_id, created_date
FROM restaurant_history, run
JOIN run ON restaurant_history.run_id = run.run_id;
The query you had before was the equivalent of the following:
SELECT run_id, restaurant_id, created_date
FROM restaurant_history
CROSS JOIN run
INNER JOIN run ON restaurant_history.run_id = run.run_id;
The reason for the error was because you had the table run listed twice in the query with no aliases to discern between the two. The ON clause referenced the run table, but it didn't know which one you meant.
Additionally, you're unintentionally creating a CROSS JOIN between restaurant_history and run - something I'm sure you don't want.
But just removing the second table from the FROM clause will still give you an error about an ambiguous column (run_id) in your SELECT statement. This column exists in both tables (as we can see from the JOIN), and without explicitly telling it which table to select from, it doesn't know how to handle the column and will throw an error.
To fix this, you will also need to alias the tables (the H and R aliases I've put in the solution).
For more information on different JOIN types, see this question:
What is the difference between "INNER JOIN" and "OUTER JOIN"?
For more information on Explicit vs Implicit JOINs, see here:
Bad habits to kick : using old-style JOINs
SELECT run_id, restaurant_id, created_date
FROM restaurant_history H
INNER JOIN run R ON H.run_id = R.run_id
Try this query
SELECT run_id, restaurant_id, created_date
FROM restaurant_history
INNER JOIN run ON restaurant_history.restaurant_id= run.run_id;
This is working:
SELECT *
FROM ((((defect
JOIN project_testcase ON
defect.Test_Id=project_testcase.Test_Id)
JOIN testcase ON
defect.Test_Id=testcase.Test_Id)
JOIN project_pm ON
project_testcase.Project_Id=project_pm.Project_Id)
JOIN employee ON
employee.Emp_id=project_pm.Emp_id)
However, this does not work:
SELECT *
FROM ((((defect
JOIN project_testcase ON
defect.Test_Id=project_testcase.Test_Id)
JOIN testcase ON
defect.Test_Id=testcase.Test_Id)
JOIN project_pm ON
project_testcase.Project_Id=project_pm.Project_Id)
JOIN employee ON
employee.Emp_id=project_pm.Emp_id)
WHERE Project_Id LIKE '%$categ%'
As I have used JOIN tables and joined using Project_Id. Is that the error?
The first thing I would do to troubleshoot this is to paste it into an SQL formatter. This will help find syntax errors and could help you see a logic error. I would recommend freeformatter.com.
Second you can get rid of the parenthesis.
The Fix
You need to specify what table to get the Project_Id in the WHERE because it is in multiple tables, but for clarity I would always specify what table it comes from.
select
*
from
defect
join
project_testcase
on defect.Test_Id=project_testcase.Test_Id
join
testcase
on defect.Test_Id=testcase.Test_Id
join
project_pm
on project_testcase.Project_Id=project_pm.Project_Id
join
employee
on employee.Emp_id=project_pm.Emp_id
where
project_testcase.Project_Id like '%$categ%'
Project_Id in the where clause is ambiguous, you need to define it as you have done on your joins ie WHERE project_pm.Project_Id like '%$categ%'
In the where clause of the 2nd query you need to tell the rdbms exactly which Project_Id field you want to filter on, since multiple tables contain the Project_Id field, e.g. project_pm.Project_Id.
Starting by removing all those unnecessary parenthesis, formatting and aliases reveals a fairly simple query underneath.
select * --This should really be the columns you actually need instead of all of them
from defect d
join project_testcase ptc on d.Test_Id = ptc.Test_Id
join testcase t on d.Test_Id = t.Test_Id
join project_pm p on ptc.Project_Id = p.Project_Id
join employee e on e.Emp_id = p.Emp_id
where p.Project_Id like '%$categ%'
Of course this begs the question of why do you have text like that in a column named Project_Id? That does not look like a project id to me. And since you are using a leading wildcard you have a nonSARGable query so you have eliminated the ability of index seeks on that column.
Given tables Contracts, Contract_Plans and Contract_Plan_Tags, can I select specific fields from all three within an inner join query?
Currently, I have
SELECT * FROM Contracts
INNER JOIN Contract_Plans
ON Contracts.ContractNum = Contract_Plans.ContractNum
INNER JOIN Contract_Plan_Tags
ON Contracts.ContractNum = Contract_Plan_Tags.ContractNum
WHERE Contract_Plan_Tags.tag_id = 44 OR Contract_Plan_Tags.tag_id = 45
This query returns all the fields, but is there any way to select the specific fields from the join tables?
I know I can do
SELECT ContractNum, ContractName FROM Contracts
...
...
but that only selects fields from Contracts, not the other tables.
You should learn about table aliases. The best table aliases are short abbreviations of the tables. You can then list the fields with the aliases:
SELECT c.ContractNum, c.ContractName, cpt.tag_id, . . .
FROM Contracts c
INNER JOIN Contract_Plans cp
ON c.ContractNum = cp.ContractNum
INNER JOIN Contract_Plan_Tags cpt
ON c.ContractNum = cpt.ContractNum
WHERE cpt.tag_id in (44, 45)
I notice that you use table names in the where clause, so I hope I understand the question correctly. You can use aliases (or table names) in the select and where (and group by and having) clauses.
You must prefix the fields by their table name if order for MySQL to distinguish them:
SELECT Contracts.This, Contract_Plan_Tags.That, Contract_Plans.There FROM Contracts
INNER JOIN Contract_Plans
ON Contracts.ContractNum = Contract_Plans.ContractNum
INNER JOIN Contract_Plan_Tags
ON Contracts.ContractNum = Contract_Plan_Tags.ContractNum
WHERE Contract_Plan_Tags.tag_id = 44 OR Contract_Plan_Tags.tag_id = 45
Yes, you can select any field from any table from the FROM clause. If two fields of two tables have the same name, then you must prefix the field with the name of the table (or else you get an error from the parser: "field name is ambiguous").
You may prefix the unambiguous field names too if you find it more readable.
In fact it works exactly the same way as in the WHERE clause.
Incidentally, the same requirement exists if you join tables from several databases. If two tables have the same name, you must prefix their name with the database name, but do not need to if the name is unambiguous.
Oh and you can also do this: SELECT table1.*, table2.some_field, table3.* FROM...
I have two tables and a foreign_key index table:
table xymply_locations
id
name
lat
lng
table xymply_categories
id
name
table xymply_categoryf_key
locid
catid
and i want to select the categories that are assigned to locid 1. How do I do this, I tried
SELECT *
FROM `xymply_categoryf_key`, xymply_categories
JOIN `xymply_categories` ON
xymply_categories.id = xymply_categoryf_key.catid
WHERE locid = 1;
but I get "Not unique table/alias: 'xymply_categories' " and I'm wondering why...?
You're mixing implicit (all tables listed in the FROM clause) and explicit JOIN styles in your code, hence the error.
SELECT xc.id, xc.name
FROM xymply_categories xc
INNER JOIN xymply_categoryf_key xck
ON xc.id = xck.catid
WHERE xck.locid = 1;
In your query, you're selecting from two tables. One of them is xymply_categoryf_key, the other is a JOIN of two instances of xymply_categories. You're using two instances of the same table, so when you write xymply_categories.id it is not clear which instance you mean - the one that is the first argument of JOIN, or that one which is the second argument? That's what "Not unique table/alias" means. If I understand correctly what you want to do, try this:
SELECT c.id, c.name FROM xymply_categories c, xymply_categoryf_key k WHERE c.id = k.catid AND k.locid = 1;
This was done without JOIN, although the evaluation of
WHERE c.id = k.catid
maybe would be faster with JOIN, I am not sure. Also, note the usage of k and c as aliases for the tables xymply_categoryf_key (k for key) and xymply_categories c (c for categories). This is how to avoid the problem of "Not unique table/alias" which occured to you before. In your case, you would use e.g.
xymply_categories a JOIN xymply_categories b WHERE a.id = ...
So, although I gave an example how to write the query without using JOIN - as I mentioned, using JOIN will maybe produce a faster query. Therefore, all you should do is to add the aliases.
Because you are "joining" xymply_catagories twice so the db wants an alias for the tables in order to know which one to go to when selecting a column.
you can do joins several ways depending on what you want. A straight inner join (which appears to be what you want) can be
select * from xymply_categoryf_key a, xymply_categories b where a.catid = b.id
WHERE b.locid = 1;
or you can also do an explicit inner join as Joe Stefanelli shows. Either of these gives you the records where there is matching info from each table.