Update with nested select in from statement does not work mysql - mysql

Here is an error I don't understand:
mysql> UPDATE gp
-> SET gp.gpid = gp.new_gpid
-> FROM (
-> SELECT gpid, ROW_NUMBER() OVER (ORDER BY [gpid]) AS new_gpid
-> FROM gp
-> ) gp;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM (
SELECT gpid, ROW_NUMBER() OVER (ORDER BY [gpid]) AS new_gpid
' at line 3
As far as I can tell nested SELECT in a FROM statement seems to be depreciated.
Am using mysql 8.0.21
Any help to make this query work would be greatly appreciated.
Thank you
EDIT 1:
What I am trying to achieve is to update the gpid column with row numbers instead of the actual AUTO_INCREMENT id, which contains gaps in between ids, the explanation in this post Change mysql auto increment id column value

The UPDATE... FROM ... syntax is not supported by MySql.
You can do it with a JOIN:
UPDATE gp
INNER JOIN (
SELECT gpid, ROW_NUMBER() OVER (ORDER BY gpid) AS new_gpid
FROM gp
) t ON t.gpid = gp.gpid
SET gp.gpid = t.new_gpid;
See a simplified demo.

Your nested query is selecting from 'gp' but is then aliased as 'gp' it can't select from itself.

Related

DELETE FROM throws a SQL Error [1064] [42000]: (conn=5159) on a query, on which a SELECT works

Trying to delete a specific amount of rows in a MySQL query, I am able to SELECT whatever I want to delete with the following command, getting the results I need:
select * from ns_cos ns where ns.created_at <>
(select max(nsa.created_at) from ns_cos nsa
where nsa.month_year = ns.month_year)
However, when I try to delete the selected data with:
delete from ns_cos ns where ns.created_at not exists
(select max(nsa.created_at) from ns_cos nsa
where nsa.month_year = ns.month_year)
I get:
SQL Error [1064] [42000]: (conn=5159) You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'ns where ns.created_at not exists (select max(nsa.created_at) from ns_cos nsa wh' at line 1
What am I doing wrong?
Your immediate issue is that not all MySQL versions support aliasing the table directly in delete from. Furthermore, though, you cannot re-open the table you delete from in the from clause.
Consider using the delete ... join syntax.
delete ns
from ns_cos ns
inner join (
select month_year, max(nsa.created_at) created_at
from ns_cos nsa
group by month_year
) ns1 on ns1.month_year = ns.month_year and ns1.created_at <> ns.created_at
EXISTS in there not posible use IN clause, but you need to enclose the table in a seprate select, so that mysql thinks it is another table
delete from ns_cos ns
where ns.created_at not IN (select max(nsa.created_at) from (SELECT * FROM ns_cos) nsa where nsa.month_year = ns.month_year)
This happens when you join tables from two schemas, no matter whether you take aliases for the table names or not.
Error
SQL Error [1064] [42000]: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '...'
delete !ALIAS! from table ALIAS ...
Strangely, only with aliases, you can get around this error in a one-step SQL. Tested in MySQL 5.7.
Try this pattern, using the alias of the table you want to delete from between delete and from:
delete t1 from table t1
join table2 t2
on t1.id = t2.id
Your code would be:
delete ns from ns_cos ns where ns.created_at not exists
(select max(nsa.created_at) from ns_cos nsa
where nsa.month_year = ns.month_year)
Other steps I checked before finding out the alias trick (do not read)
I tried it with a view of the other schema's table in the same schema, that is not enough.
One way to get around this is to make a copy of the table in the same schema (and delete that copy afterwards).
You might also somehow make a full "linked server link" like in T-SQL [linkedservername].DB1.Schema.Table1 at How to join two tables if they are in different schemas Your code is on the same server, but this might still help jumping over to the other schema, untested.

Selecting Multiple Fields in a Find Statement SQL

So basically, I am trying to select a row from my database, based on two values, I have tried doing
SELECT FROM users WHERE first = 'Bob' AND last = 'Stevenson';
but when I do it it gives this error:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'FROM users WHERE first = 'Robert' AND last = 'Westbury'' at line 1
Thanks in advance,
Robert
You need to specify what column(s) do you want to select, SELECT statement should be followed by the column names or by * to select all the columns:
SELECT * FROM users WHERE first = 'Bob' AND last = 'Stevenson'
Dude, it's Select (* OR <column_name_1>, <column_name_2>... ) From <table_name> where <condition>;

MySql subquery error with delete statement

I'm learning sql from these wikibooks pages and I'm trying to answer the last question "Remove all boxes from saturated warehouses" using mysql syntax. The following is what I came up with on my own mainly using previous answers from the same page.
delete from Boxes as b
where b.Warehouse in (
select w.Code
from ( select *
from Warehouses) as w
where w.Capacity < ( select count(*)
from Boxes bb inner join Warehouses ww
on bb.Warehouse = ww.Code
group by bb.Contents) ) ;
The query for this question on the site is generating
this solution doesn't work with mysql 5.0.67
ERROR 1093 (HY000): You can't specify target table 'Boxes' for update in FROM clause
That's why I'm using multiple sub queries as a way to come around this mysql message. However, I have an error in my query and therefore it's not running.
Error Code: 1064. You have an error in your SQL syntax; check the
manual that corresponds to your MySQL server version for the right
syntax to use near 'as b where b.Warehouse in ( select w.Code
from ( sel' at line 1
Any idea?
I assume Boxes and Warehouse are tables, you gave Boxes an alias and used it on the Warehouse table, that's probably why it didn't work. Maybe you should try with a query after 'delete from'.
I think your warehouses table returns from than one columns (since * is used). Replace * with the column u want to get the output from.

Delete duplicates for multiple columns in JOIN on same table

I am trying to make a delete from joined same table like this:
DELETE FROM `sp10_seo_url` AS sp1 JOIN
(
SELECT seo_url_pk, COUNT(*) AS maxc
FROM `sp10_seo_url`
GROUP BY seo_url_entity_type, seo_url_entity_id, seo_url_language_fk
HAVING maxc > 1
) AS sp2
ON sp1.seo_url_pk = sp2.seo_url_pk
However I am getting a mysql error
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AS sp1 JOIN ( SELECT seo_url_pk, COUNT(*) AS maxc FROM `sp10_s' at line 1
And I am not sure at all where the error is. The inner query runs just fine and returns the expected set of results. The "ON" keys are properly named (same since we are talking about the same table).
I guess the idea of the query is pretty clear (clean the table of different rows have the same set of values for the three "group by" columns. Is there another way to do this?
Thanks!
you can "cheat" mysql with a double indirection (as explained here Deleting a row based on the max value):
delete from `sp10_seo_url`
where seo_url_pk in (
select seo_url_pk from (
SELECT seo_url_pk
FROM `sp10_seo_url` sp1,
(
SELECT seo_url_entity_type, seo_url_entity_id, seo_url_language_fk
FROM `sp10_seo_url`
GROUP BY seo_url_entity_type, seo_url_entity_id, seo_url_language_fk
HAVING count(*) > 1
) sp2
where sp1.seo_url_entity_type = sp2.seo_url_entity_type
and sp1.seo_url_entity_id = sp2.seo_url_entity_id
and sp1.seo_url_language_fk = sp2.seo_url_language_fk
) t
);
http://sqlfiddle.com/#!2/899ff5/1

Running EXPLAIN on MySQL query is giving a syntax error

I have a basic query that looks like the following that's running slow, so I'm trying to figure out where there's missing indexes or other optimizations I can make:
drop table weights;
CREATE TABLE weights engine=myisam
SELECT 'K' AS STAT,
z.WEIGHT,
COUNT(*) AS SAMPLE,
round(AVG(z.FINAL_2Y),15) AS 2Y,
round(AVG(z.FINAL_3Y),15) AS 3Y,
round(AVG(z.FINAL_4Y),15) AS 4Y,
round(AVG(z.FINAL_5Y),15) AS 5Y,
round(AVG(z.FINAL_6Y),15) AS 6Y
FROM
( SELECT /* insert big query here */ ) z
GROUP BY WEIGHT;
This query is running awfully slow so I'm trying to make one simple change with the following:
drop table sp_weights_holding_table
CREATE TABLE sp_weights_holding_table engine=myisam
EXPLAIN SELECT 'K' AS STAT,
z.WEIGHT,
COUNT(*) AS SAMPLE,
round(AVG(z.FINAL_2Y),15) AS 2Y,
round(AVG(z.FINAL_3Y),15) AS 3Y,
round(AVG(z.FINAL_4Y),15) AS 4Y,
round(AVG(z.FINAL_5Y),15) AS 5Y,
round(AVG(z.FINAL_6Y),15) AS 6Y
FROM
( SELECT /* insert big query here */ ) z
GROUP BY WEIGHT;
As soon as I pop the EXPLAIN in, I get a syntax error. I'm using MySQL 5.6.13 on Amazon RDS. The error looks like the following:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'EXPLAIN SELECT 'K' AS STAT,
z.WEIGHT,
COUNT(*) AS SAMPLE,
r' at line 2
You must semicolon the end of the sql command.
Change to
drop table sp_weights_holding_table;
CREATE TABLE sp_weights_holding_table engine=myisam;
EXPLAIN SELECT 'K' AS STAT,
....
Use the EXPLAIN with the SELECT query alone without the first two lines for dropping/creating the table:
EXPLAIN SELECT 'K' AS STAT,
z.WEIGHT,
COUNT(*) AS SAMPLE,
round(AVG(z.FINAL_2Y),15) AS 2Y,
round(AVG(z.FINAL_3Y),15) AS 3Y,
round(AVG(z.FINAL_4Y),15) AS 4Y,
round(AVG(z.FINAL_5Y),15) AS 5Y,
round(AVG(z.FINAL_6Y),15) AS 6Y
FROM
( SELECT /* insert big query here */ ) z
GROUP BY WEIGHT;