The following query works with mysql 5.x but errors out on mysql 8.0.x:
SET @num := 0, @website_id_host := 0;
SELECT website_id_host, url, date_inserted, row_number
FROM (
SELECT website_id_host, url, date_inserted, @num := if(@website_id_host = website_id_host, @num+1, 1) as row_number, @website_id_host := website_id_host as dummy1
FROM (
SELECT website_id_host, url, date_inserted
FROM records
WHERE date_inserted between '2019-11-14 00:00:00' and '2019-11-14 23:59:59' and website_id_host is not null
ORDER BY website_id_host, date_inserted desc
) intermediate
) final
where row_number <=100;
The error I get is:
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 'from ( SELECT website_id_host, url, date_inserted, @num := if(@website_id_host '
at line 2
The error isn't very clear about what is wrong. Can anybody help figure out why it's now failing?
Just rename row_number
. It is now a function:
SELECT website_id_host, url, date_inserted, seqnum
FROM (SELECT website_id_host, url, date_inserted,
@num := if(@website_id_host = website_id_host, @num+1, 1) as seqnum,
@website_id_host := website_id_host as dummy1
FROM (SELECT website_id_host, url, date_inserted
FROM records
WHERE date_inserted between '2019-11-14 00:00:00' and '2019-11-14 23:59:59' and website_id_host is not null
ORDER BY website_id_host, date_inserted desc
) intermediate
) final
where seqnum <= 100;
This code has a hidden bug and may not always work. As explained in the documentation :
The order of evaluation for expressions involving user variables is undefined. For example, there is no guarantee that
SELECT @a, @a:=@a+1
evaluates @a first and then performs the assignment.
Your code assigns a variable and using it in the same SELECT
-- and depending on the order of evaluation. That is specifically documented as not being reliable.
In addition, the use of variables is being phased out, as explained in the documentation :
Previous releases of MySQL made it possible to assign a value to a user variable in statements other than SET. This functionality is supported in MySQL 8.0 for backward compatibility but is subject to removal in a future release of MySQL.
So, the right way to write this in MySQL 8+ is to use row_number()
:
SELECT r.*
FROM (SELECT website_id_host, url, date_inserted,
ROW_NUMBER() OVER (PARTITION BY website_id_host ORDER BY date_inserted DESC) as seqnum
FROM records r
WHERE date_inserted >= '2019-11-14' and
date_inserted < '2019-11-15' and
website_id_host is not null
) r
WHERE seqnum <= 100
Note that I also simplified the date comparisons.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.