RANK query using PARTITION BY fails in mysql - 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

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)

SQL Query about percentage selection

I am trying to write a query for a condition:
If >=80 percent (4 or more rows as 4/5*100=80%) of the top 5 recent rows(by Date Column), for a KEY have Value =A or =B, then change the flag from fail to pass for the entire KEY.
Here is the input and output sample:
I have highlighted recent rows with green colour in the sample.
Can someone help me in this?
I tried till finding the top 5 recent rows by the foll code:
select * from(
select *, row_number() over (partition by "KEY") as 'RN' FROM (
select * from tb1
order by date desc))
where "RN"<=5
Couldnt figure what to be done after this
Test this:
WITH
-- enumerate rows per key group
cte1 AS ( SELECT *,
ROW_NUMBER() OVER (PARTITION BY `key` ORDER BY `date` DESC) rn
FROM sourcetable ),
-- take 5 recent rows only, check there are at least 4 rows with A/B
cte2 AS ( SELECT `key`
FROM cte1
WHERE rn <= 5
GROUP BY `key`
HAVING ( SUM(`value` = 'A') >= 4
OR SUM(`value` = 'B') >= 4 )
-- AND SUM(rn = 5) )
-- update rows with found key values
UPDATE sourcetable
JOIN cte2 USING (`key`)
SET flag = 'PASS';
5.7 version – Ayn76
Convert CTEs to subqueries. Emulate ROW_NUMBER() using user-defined variable.

The same SQL but have different result

ps:the description show detail with the href: https://segmentfault.com/q/1010000014649728
I run the follow sql :
select * from
(
select *,(#num2 :=
(if(#GROUP199=`C_ISHOT`,#num2+1,if(#GROUP199:=`C_ISHOT`,1,1)))) row_number
from city_code order by C_ISHOT
) result
where row_number<=10
the first run result show the table total numbers,
but the second run result is my expected。 what's the matter with it,and how can I resolve that?
The variables are not initialized.
select *
from ( select *, (#num2 :=(if(#GROUP199=C_ISHOT,#num2+1,if(#GROUP199:=C_ISHOT,1,1)))) row_number
from city_code, ( SELECT #num2 := 0, #GROUP199 := 0 ) init_vars
order by C_ISHOT ) result
where row_number<=10

mysql sql error when using the row_number

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;

Equivalent of MSSQL with statement in MYSQL

is there any equivalent to the following statement in mysql ?
With Tmp1 as (
Select Distinct EmpID, TypeID
From tb_deductionBalance
), Tmp2 as (
Select *,
row_number() OVER ( order by empID /* no employeeID in Tmp1 */) as RowNum
From Tmp1
)
Select * From Tmp2
Where RowNum Between #Start and #End
I have to migrate an mssql database to mysql and there are plenty of such statements which would take much more time to recreate in mysql if it cannot be translated.
Thanks
SELECT DISTINCT EmpID, TypeID
FROM tb_deductionBalance
ORDER BY empID
LIMIT YourStartNumber - 1, YourEndNumber - YourStartNumber
Unfortunately, you can't use variables in LIMIT, so you'll need to use actual integers there. For instance, if you want results from the rows 3 to 10, you'll need to use:
SELECT DISTINCT EmpID, TypeID
FROM tb_deductionBalance
ORDER BY empID
LIMIT 2, 7