This question already has answers here:
What is the error "Every derived table must have its own alias" in MySQL?
(4 answers)
Closed 6 years ago.
I am trying to make a CROSS JOIN between "Selected" columns in two tables,
For example : Table 1 (a, b, c) -- Table 2 (a, b, d)
I want to select a and b from each table and then join them, but I keep getting this error :
Every derived table must have its own alias
I know this is because I need to name any derived table, but I still can't figure what's the problem and how to fix it even after searching online. This is the query :
SELECT (x.targetNumber, x.name, x.lat, x.lng)
FROM ((SELECT (u.name, u.targetNumber, u.password)
FROM Users AS u WHERE 'target' = u.type)
CROSS JOIN
(SELECT (l.targetNumber, l.password, l.lat, l.lng) FROM Location AS l)
WHERE (u.targetNumber = l.targetNumber AND u.password = l.password )) AS x;
So far it seems your query is supposed to be this:
select u.targetnumber, u.name, l.lat, l.lng
from users u
join location l on l.targetNumber = u.targetNumber and l.password = u.password
where u.type = 'target';
only that you want to apply some tricks to force the DBMS to follow some execution plan that you consider best. In doing so you make your query completely unreadable and introduce errors.
As you can see there is no cross join. You are not looking for getting all possible combinations of two data sets at all - which is what a cross join is.
And anyway this is not how SQL works. You are to write the query straigh-forward telling the DBMS what to do. The DBMS decides then how to do it.
The short answer is to move the closing parentheses from right after FROM Location AS l) to just in front of the as and remove the alias from the select list of the subquery:
...(SELECT targetNumber, password, lat, lng FROM Location) AS l...
Slightly longer answer: I do not even understand why you have subqueries in the from clause at all. You can simply join these 2 tables.
Related
Situation Overview
The current question is a problem about selecting values from two tables table A (material) and table B (MaterialRevision). However, The PK of table A might or Might not exist in Table B. When it doesnt exists, the query described in this question wont return the values of table A, but IT SHOULD. So basically here's whats happening :
The query is only returning values when A.id exists in B.id, when In fact, I need it to return values from A when A.id ALSO dont exist in B.id.
Problem:
Suppose two tables. Table Material and Table Material Revision.
Notice that the PK idMaterial is a FK in MaterialRevision.
Current "Mock" Tables
Query Objective
Obs: remember these two tables are a simplification of the real
tables.
For each Material, print the material variables and the last(MAX) RevisionDate from MaterialRevision. In case theres no RevisionDate, print BLANK ("") for the "last revision date".
What is wrongly happening
For each Material, print the material variables and the last(MAX) RevisionDate from MaterialRevision. In case theres no Revision for the Material, doesnt print the Material (SKIP).
Current Code
SELECT
Material.idMaterial,
Material.nextRevisionDate,
Material.obsolete,
lastRevisionDate
FROM Material,
(SELECT MaterialRevision.idMaterial, max(MaterialRevision.revisionDate) as "revisionDate" from MaterialRevision
GROUP BY MaterialRevision.idMaterial
) AS Revision
WHERE (Material.idMaterial = Revision.idMaterial AND Material.obsolete = 0)
References and Links used to reach the state described in this question
Why is MAX() 100 times slower than ORDER BY ... LIMIT 1?
MySQL get last date records from multiple
MySQL - How to SELECT based on value of another SELECT
MySQL Query Select where id does not exist in the JOIN table
PS I hope this question is correctly understood since it took me a lot of time to build it. I researched a lot in stackoverflow and after
several failed attempts I had no option but to ask for help.
You should use JOIN :
SELECT m.idMaterial, m.nextRevisionDate, mr.revisionDate AS "lastRevisionDate"
FROM Material m
LEFT JOIN MaterialRevision AS mr ON mr.idMaterial = m.idMaterial AND mr.revisionDate = (
SELECT MAX(ch.revisionDate) from MaterialRevision ch
WHERE mr.idMaterial = ch.idMaterial)
WHERE m.obsolete = 0
Here is an explanation of what INNER JOIN, LEFT JOIN and RIGHT JOIN are. (You will love them if you often cross tables in your queries)
As m.obsolete will always be true, I ommited it in the SELECT clause
You should use the left outer join instead of using the cross product.
You're query should be something like this:
SELECT idMaterial, nextRevisionableDate, obsolete,
revisionDate AS lastRevisionDate
FROM Material
LEFT OUTER JOIN MaterialRevision AS mr On
Material.idMaterial = MaterialRevision.id
AND mr.revisionDate = (SELECT MAX(ch.revisionDate) from MaterialRevision ch
WHERE mr.idMaterial = ch.idMaterial)
WHERE obsolete = 0;
Here you can find some documentation about types of join.
This question already has an answer here:
MySQL Inner Join Query Syntax error
(1 answer)
Closed 4 years ago.
In my DB I have 2 Tables. One for user Login information and one for general information.
Im trying to write a query that will select the column "firstname" from rows where the FK "users_id" is the same as the logged in users ID.
Before doing anything in PHP Im running the query in my database, so the logged in users ID, which would normally be a variable, is replaced with the id of my testuser.
This is my query:
SELECT b6vjp_user_info.firstname
FROM b6vjp_user_info
WHERE b6vjp_user_info.users_id LIKE 243
INNER JOIN b6vjp_users ON b6vjp_user_info.users_id=b6vjp_users.id;
And here is my (censored for security reasons) Login Table named "b6vjp_users":
And here is my other table named "b6vjp_user_info":
The error is:
#1064 - Mistake in SQL-Syntax. 'INNER JOIN b6vjp_users ON b6vjp_user_info.users_id=b6vjp_users.id LIMIT 0, 25' on row 4
Now fyi I translated that, because my work environment is in german. But im sure you know what a Syntax-Error is.
Anyways I checked the JOIN Part of my query over and over again and looked up the JOIN tutorial on W3Schools. But there is no apparent mistake.
Does anybody see what I somehow fail to?
Put the WHERE clause after the (last) ON clause.
I strongly recommend using table aliases. You also need to fix the order of your SQL clauses. So:
SELECT ui.firstname
FROM b6vjp_user_info ui JOIN
b6vjp_users u
ON ui.users_id = u.id
WHERE ui.users_id = '243';
Or, more simply without the JOIN:
SELECT ui.firstname
FROM b6vjp_user_info ui
WHERE ui.users_id = '243';
Notes:
The operand to LIKE should be a string. So, make it a string! Implicit type conversion causes all sorts of problems.
If you are not using wildcards, I think = is more informative. If users_id is really a number, then just use = 243 rather than LIKE.
WHERE goes after the FROM clause. JOIN is an operator in the FROM clause.
The JOIN is not necessary. Unless you are fetching columns from the users table (or need it for filtering which is highly doubtful), don't bother with it.
you have to put where after on clause
SELECT b6vjp_user_info.firstname
FROM b6vjp_user_info
INNER JOIN
b6vjp_users ON
b6vjp_user_info.users_id=b6vjp_users.id
WHERE b6vjp_user_info.users_id =243 // i think it int field so no need to use like operator
This question already has answers here:
How can I do a FULL OUTER JOIN in MySQL?
(15 answers)
Closed 6 years ago.
Here i am trying to run one query in MySQL editor and getting one problem
Here is my query
select *
FROM my_db.persons FULL JOIN
my_db.employee
ON persons.PersonID=employee.PersonID;
Any help would be appreciated
MySQL doesn't support FULL JOIN, so perhaps that is the problem. In any case, I prefer shorter table aliases:
select *
FROM my_db.persons p LEFT JOIN
my_db.employee e
ON p.PersonID = e.PersonID;
This, of course, assumes that the PersonID column exists in both tables.
Oh, I see why you got the error. Perhaps this will explain:
select *
FROM my_db.persons full JOIN
my_db.employee e
ON full.PersonID = e.PersonID;
That is, because MySQL doesn't support FULL JOIN, the full is treated as a table alias.
Check if PersonID column exists on Persons table. Make sure the spellings are exactly the same as in the table structure. Also check the case. Some IDE are case sensitive.
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.
I get out of memory exception in my application, when the condition for IN or NOT IN is very large. I would like to know what is the limitation for that.
Perhaps you would be better off with another way to accomplish your query?
I suggest you load your match values into a single-column table, and then inner-join the column being queried to the single column in the new table.
Rather than
SELECT a, b, c FROM t1 WHERE d in (d1, d2, d3, d4, ...)
build a temp table with 1 column, call it "dval"
dval
----
d1
d2
d3
SELECT a, b, c FROM t1
INNER JOIN temptbl ON t1.d = temptbl.dval
Having to ask about limits when either doing a SQL query or database design is a good indicator that you're doing it wrong.
I only ever use IN and NOT IN when the condition is very small (under 100 rows or so). It performs well in those scenarios. I use an OUTER JOIN when the condition is large as the query doesn't have to look up the "IN" condition for every tuple. You just have to check the table that you want all rows to come from.
For "IN" the join condition IS NOT NULL
For "NOT IN" the join condition IS NULL
e.g.
/* Get purchase orders that have never been rejected */
SELECT po.*
FROM PurchaseOrder po LEFT OUTER JOIN
(/* Get po's that have been rejected */
SELECT po.PurchaesOrderID
FROM PurchaseOrder po INNER JOIN
PurchaseOrderStatus pos ON po.PurchaseOrderID = pos.PurchaseOrderID
WHERE pos.Status = 'REJECTED'
) por ON po.PurchaseOrderID = por.PurchaseOrderID
WHERE por.PurchaseOrderID IS NULL /* We want NOT IN */
I"m having a similar issue but only passing 100 3 digit ids in my IN clause. When I look at the stack trace, it actually cuts off the comma separate values in the IN clause. I don't get an error, I just don't get all the results to return. Has anyone had an issue like this before? If its relevant, I'm using the symfony framework... I'm checking to see if its a propel issue but just wanted to see if it could be sql
I have used IN with quite large lists of IDs - I suspect that the memory problem is not in the query itself. How are you retrieving the results?
This query, for example is from a live site:
SELECT DISTINCT c.id, c.name FROM categories c
LEFT JOIN product_categories pc ON c.id = pc.category_id
LEFT JOIN products p ON p.id = pc.product_id
WHERE p.location_id IN (
955,891,901,877,736,918,900,836,846,914,771,773,833,
893,782,742,860,849,850,812,945,775,784,746,1036,863,
750,763,871,817,749,838,986,794,867,758,923,804,733,
949,808,837,741,747,954,939,865,857,787,820,783,760,
911,745,928,818,887,847,978,852
) ORDER BY c.name ASC
My first pass at the code is terribly naive and there are about 10 of these queries on a single page and the database doesn't blink.
You could, of course, be running a list of 100k values which would be a different story altogether.
I don't know what the limit is, but I've run into this problem before as well. I had to rewrite my query something like this:
select * from foo
where id in (select distinct foo_id from bar where ...)