mysql sql error when using the row_number - mysql

This query is throwing error, it seems correct but i am getting an error
WITH Rows AS (SELECT *,
ROW_NUMBER() OVER (ORDER BY userid asc) as [Row]
FROM users
WHERE 1=1
)
SELECT * FROM Rows
WHERE Row >= 1 and Row <= 10
error i am getting while running the above statement is:
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 'Rows AS (SELECT *, ROW_NUMBER() OVER (ORDER BY userid asc)
FROM users
' at line 1

Your error is on Rows because MySQL does not recognize the CTE.
Then, MySQL also does not recognize [, so you want to use a more reasonable name. In MySQL 8+, that would be something like:
WITH Rows AS (
SELECT *,
ROW_NUMBER() OVER (ORDER BY userid asc) as seqnum
FROM users
)
SELECT *
FROM Rows
WHERE seqnum <= 10;
You don't need to compare to 1. That is definitional.
Of course, this, in turn, is overkill. The CTE is unnecessary:
SELECT *,
ROW_NUMBER() OVER (ORDER BY userid asc) as seqnum
FROM users
ORDER BY userid
LIMIT 10;
But this will still fail, because MySQL versions started recognizing CTEs and window functions in the same version.
So, you can just use variables:
SELECT u.*, (#rn := #rn + 1) as seqnum
FROM users u CROSS JOIN
(SELECT #rn := 0) params
ORDER BY userid
LIMIT 10;

Related

Select Row Number in MySQL

I want to get the rownumber of each row from a MySQL Table. I already read this article and tried the suggested select statement as below,
SELECT #rownum:=#rownum + 1 as row_number,
t.*
FROM (
select * from myTable
) t,
(SELECT #rownum := 0) r
But I am getting in syntax error as below when I ran in Dbeaver,
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 'row_number,
t.*
FROM (
select * from myTable
) t,
(SELECT #r' at line 1
Can someone please help? I am new to MySQL. I am using version 8.0. Once it's tested I would basically want to use this select in my Apache Spark Code
use this one:
SELECT #rownum:=#rownum + 1 as row_num,
t.*
FROM (
select * from myTable
) t,
(SELECT #rownum := 0) r;
row_number is a reserved keyword of mysql, you can not use it as alias or for any other purpose.
Try something like this.
SELECT *,
ROW_NUMBER() OVER(PARTITION BY 'some column' ) AS row_num
FROM my_table
(https://www.javatpoint.com/mysql-row_number-function)

RANK query using PARTITION BY fails in mysql

I tried below query to partition by but which fails with below query, the inner query works
select issueid, task_type, assignee, timeoriginalestimate, CREATED,
dense_rank() over ( partition by issueid order by CREATED desc ) as rank
from(
--- Complex query with p.pname, i.issuenum, cg.issueid, it.pname task_type, i.assignee, i.timeoriginalestimate, cg.CREATED, columns which works fine
)
Exception:
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 '( partition by issueid order by CREATED desc ) as rank
from(
SELECT p.pna' at line 3
Update:
SELECT VERSION(); -- 5.6.27
Although your MySQL version do not support Window function, I am letting this is not the issue. Guess you have a higher version and window function is supported.
Now, in your query you have defined the Alias of a column name to "Rank" which is a reserved keyword for your database and you can not use that as column name.
Hope this below hints will help you-
select
issueid,
task_type,
assignee,
timeoriginalestimate,
CREATED,
dense_rank() over ( partition by issueid order by CREATED desc ) as rn -- change the alias name
from(
-- Your subquery
) A -- Also need to give a Alias name to your sub query
Finally, if you have lower version check this LINK for help to get an idea of creating Row_number or Ranking for MySQL older versions.
In addition, this following sample query will really help you finding solution for different type row_number in mysql-
SET #simple_row_number := 0;
SET #id_wise_row_number := 0;
SET #dense_rank_per_id := 0;
SET #prev := 0;
SELECT *,
#simple_row_number := #simple_row_number + 1 AS simple_row_number,
#id_wise_row_number := IF(issueid > #prev, #id_wise_row_number + 1, #id_wise_row_number) AS id_wise_row_number,
#dense_rank_per_id :=IF(issueid > #prev,1, #dense_rank_per_id + 1) AS dense_rank_per_id,
#prev := A.issueid Prev_IssueId
FROM (
SELECT 1 issueid, '20200601' CREATED UNION ALL
SELECT 1 issueid, '20200401' CREATED UNION ALL
SELECT 1 issueid, '20200501' CREATED UNION ALL
SELECT 1 issueid, '20200201' CREATED UNION ALL
SELECT 1 issueid, '20200301' CREATED UNION ALL
SELECT 2 issueid, '20200301' CREATED UNION ALL
SELECT 2 issueid, '20200201' CREATED UNION ALL
SELECT 2 issueid, '20200401' CREATED
) A
ORDER BY issueid, CREATED DESC

SELECT Where ID in (List of IDs) and limit records of each IDs in MySQL

I have met a situation that I have a list of IDs of a Store table and need to fetch the latest 10 files from each store.
SELECT *
FROM tblFiles
WHERE storeId in (IDs)
ORDER BY createdDate DESC
LIMIT 10
But, this limits the whole results. I found an answer to a similar SO question. But, the answer recommends using loop for each ID. This results in multiple DB hit.
Another option is to fetch all records and group them in the code. But, this will be heavy if there are large no.of records.
It'll be nice if it can be handled at the query level. Any help will be appreciated.
NB: The tables used here are dummy ones.
Pre-MySQL 8.0, the simplest method is probably variables:
select f.*
from (select f.*,
(#rn := if(#s = storeId, #rn + 1,
if(#s := storeId, 1, 1)
)
) as rn
from (select f.*
from tblfiles f
where storeId in (IDs)
order by storeId, createdDate desc
) f cross join
(select #s := 0, #rn := 0) params
) f
where rn <= 10;
In MySQL 8+ or MariaDB 10.3+, you would simply use window functions:
select f.*
from (select f.*,
row_number() over (partition by storeid order by createdDate desc) as seqnum
from tblfiles f
) f
where seqnum <= 10;
In older versions of MySQL and MariaDB, the innermost subquery may not be needed.
use select in where
SELECT * from tblFiles where storeId in (SELECT id from store ORDER BY datefield/id field desc limit 10)
You could workaround it with an UNIONed query, where each subquery searches for a particular id and enforces a LIMIT clause, like :
(SELECT *
FROM tblFiles
WHERE storeId = ?
ORDER BY createdDate DESC
LIMIT 10)
UNION
(SELECT *
FROM tblFiles
WHERE storeId = ?
ORDER BY createdDate DESC
LIMIT 10)
...
With this solution only one db hit will happen, and you are guarantee to get the LIMIT on a per id basis. Such a SQL can easily be generated from within php code.
Nb : the maximum allowed of UNIONs in a mysql query is 61.

missing parenthesis error in Mysql server

I am using the following code in MySQL server to get entries between 2 to 5 from table 'new_table' but I am receiving 'missing parenthesis' error, I have checked every aspect.
SELECT * FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY salary ASC) AS row number
FROM pact
) as temp table name
WHERE rownumber IN (2,5)
if your using a MySql-Server there is nothing like ROW_NUMBER()
but you could try something like this (UNTESTET):
SELECT * FROM (
SELECT
#num := if(#type = type, #num + 1, 1) as rownumber
FROM pact
ORDER BY salary ASC
) as temp_table_name
WHERE rownumber IN (2,5)
You can't use space in alias
SELECT * FROM (
SELECT
ROW_NUMBER() OVER (ORDER BY salary ASC) AS rownumber
FROM pact
) as temp_table_name
WHERE rownumber IN (2,5)

Is there any syntax error because, as per my understanding, the query is perfect [duplicate]

This question already has answers here:
ROW_NUMBER() in MySQL
(26 answers)
Closed 6 years ago.
Please let me know if there is any syntax error because, as per my understanding, the query is perfect:
mysql> SELECT Cust_Id,Plan_Id FROM(SELECT Cust_Id,Plan_Id,ROW_NUMBER() OVER (PARTITION BY Cust_Id ORDER BY cnt DESC) AS RN FROM(SELECT Cust_Id,Plan_Id,COUNT(1) as cnt FROM customer GROUP BY (Cust_Id,Plan_Id))) WHERE RN =1;
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 '(PARTITION BY Cust_Id ORDER BY cnt DESC) AS RN FROM(SELECT Cust_Id,Plan_Id,COUNT'
at line 1
MYSQL does not support ROW_NUMBER().
You have to rewrite your query as below
SELECT Cust_Id,Plan_Id
FROM (
SELECT Cust_Id,Plan_Id,
#row_num := IF(#prev_value=T.Cust_Id,#row_num+1,1) AS RN,
#prev_value := T.Cust_Id
FROM (
SELECT Cust_Id,Plan_Id,COUNT(1) as cnt
FROM customer
GROUP BY (Cust_Id,Plan_Id)
) T,
(SELECT #row_num := 1) x,
(SELECT #prev_value := 0) y
)S WHERE RN =1;