I have no idea why these SQL command doesnt work - mysql

So I have an Xampp server with phpmyadmin and I usered this command, which always worked:
WITH temptable AS (SELECT *, ROW_NUMBER() OVER (ORDER BY character_ID DESC)
AS t FROM characters) SELECT * FROM temptable WHERE t BETWEEN 0 AND 10;
Now I got a database on a real server and it doesent work anymore. So I looked for other commands on the internet and always found this one on several websites:
SELECT
ROW_NUMBER() OVER(ORDER BY Character_ID ASC) AS t,
Charactername
FROM characters WHERE t < 5;
I looked over several websites and it doesnt work for me and i dont know why.
The syntax in Phpmyadmin doesnt mark anything wrong when i write this command but i got still the error:
You have an error in your SQL syntax;
Maybe someone knows why?

You cannot filter by columns defined in the SELECT. If you are using MySQL (or MariaDB), you can use the HAVING clause:
SELECT ROW_NUMBER() OVER(ORDER BY Character_ID ASC) AS t,
Charactername
FROM characters
HAVING t < 5;
These databases extend the use of the HAVING clause for non-aggregation queries, and it allows the use of column aliases for filtering.

Filtering aggregation doesn't work that way in select.Modify your query as below,
SELECT * FROM
(
SELECT
ROW_NUMBER() OVER(ORDER BY Character_ID ASC) AS t,
Charactername
FROM characters) Characternametab
WHERE t < 5;

Related

SQL: LIMIT and OFFSET to find median

I am trying to find median for odd number of floats. I used the following code for this reason -
select a from tab1
limit 1 offset (count(a) div 2) - 1
But, this code is giving syntax error. I am using MySQL. Any help/ suggestion towards solving the problem will be highly appreciated.
You cannot use expressions in the limit for MySQL. You could use a window function:
select t.*
from (select tab1.*,
row_number() over (order by a) as seqnum,
count(*) over () as cnt
from tab1
) t
where seqnum = (cnt div 2) - 1 ;
Note: This follows the same logic you have in your question, but using window functions instead of limit. There are other ways to calculate the median -- and this isn't strictly speaking the median because it doesn't work for both even and odd numbers of rows.

Alternative to using Variable in a View

I need some assistance building a SQL statement that will output the top 5 retired assets per client that can be put into a SQL View.
I have built the following SQL statement but it will not work within a view and need an alternative.
SET #row_number := 0;
SELECT DISTINCT NAME, RetiredDate, COMMENT,
#row_number:=CASE WHEN #client_ID=clientID THEN #row_number+1 ELSE 1 END AS num,
#client_ID:=clientID ClientID
FROM `retiredassets`
WHERE `retiredassets`.`ClientID` IN(SELECT clientID FROM `clients`)
HAVING num <=5
Does anyone have any suggestions for me? The above statement works flawlessly but cannot work within a SQL View.
In MySQL 8.0 this should be:
WITH cte AS (
SELECT r.NAME, r.RetiredDate, r.COMMENT,
ROW_NUMBER() OVER (PARTITION BY r.ClientID ORDER BY ...) AS num,
r.ClientID
FROM retiredassets
JOIN clients USING (ClientID)
)
SELECT * FROM cte WHERE num <= 5;
I left ... because I don't know what your ordering is. Your original query doesn't specify an order, so you'll have to choose one.
Re your comment.
If you can't upgrade to MySQL 8.0, and you can't use variables in a VIEW definition, then you can't use a VIEW. You will have to write out the full query when you use it, until you can upgrade to MySQL 8.0.

MySQL throwing error 1064, doesn't seem to recognize OVER command

My query is:
SELECT *,
ROW_NUMBER() OVER (ORDER BY score ASC)
FROM submissions
The error message I receive 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 '(ORDER BY score ASC) FROM submissions LIMIT 0, 25' at line 2
I am running this query in phpMyAdmin. I notice that OVER is not colored blue, nor does is it suggested as I type, unlike other command words (ORDER, ASC, etc).
This simpler query runs just fine:
SELECT * FROM submissions
I've tried putting things in quotes, using the RANK function instead, and fiddling with whitespace, but the query still doesn't run. What is wrong here?
My guess is that you are running a version of MySQL which is earlier than 8+, one which does not support ROW_NUMBER. There are a few options for simulating ROW_NUMBER in earlier versions of MySQL. One is to use user variables:
SELECT *,
(#row_number:=#row_number + 1) AS rn
FROM submissions, (SELECT #row_number := 0) tmp
ORDER BY score;

SQL ROW_NUMBER gives error

I need to order rows in MySQL and assign a number to each row according to that order. ORDER BY is working as intended but not ROW_NUMBER().
This works:
USE my_database;
SELECT
id
,volume
FROM my_table
ORDER BY volume;
This does not work:
USE my_database;
SELECT
id
,volume
,ROW_NUMBER() over(ORDER BY volume)
FROM my_table
ORDER BY volume;
I get this error message:
SELECT id ,volume ,ROW_NUMBER() over(ORDER BY volume) FROM my_table ORDER BY volume 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 '(ORDER BY volume) FROM my_table ORDER BY vol' at line 4 0.000 sec
What am I doing wrong and how do I make it work?
I also tried RANK() and DENSE_RANK() which gives the same problem.
There are no such things as ROW_NUMBER() or RANK() in MySQL. Try the following :
USE my_database;
SET #row_number = 0;
SELECT id
, volume
, #row_number := #row_number + 1 AS rank
FROM my_table
ORDER BY volume;
The function ROW_NUMBER() does not exist in MySQL.
However, you can replicate it, possibly: http://www.mysqltutorial.org/mysql-row_number/
The row_number is a ranking function that returns a sequential number
of a row, starting from 1 for the first row. We often want to use the
row_number function to produce the specific reports we need.
Unfortunately, MySQL does not provide row_number like Microsoft SQL
Server and Oracle. However, in MySQL, you can use session variables to
emulate the row_number function.
example:
SET #row_number = 0;
SELECT
(#row_number:=#row_number + 1) AS num, firstName, lastName
FROM
employees
LIMIT 5;
MySQL introduced the ROW_NUMBER() function since version 8.0.

MySql using correct syntax for the over clause

What is the correct syntax to get the over clause to work in mysql?
I would like to see the total sms's sent by each user without grouping it with the group by clause.
SELECT
username,
count(sentSmsId) OVER (userId)
FROM
sentSmsTable,
userTable
WHERE
userId = sentUserId;
MySQL 8 has got the window functions! Therefore, you can write your query in it like this:
SELECT username,
count(sentSmsId) OVER (partition by userId)
FROM sentSmsTable
JOIN userTable ON userId = sentUserId;
There is no OVER clause in MySQL that I know of, but here is a link that might assist you to accomplish the same results:
http://explainextended.com/2009/03/10/analytic-functions-first_value-last_value-lead-lag/
Hope this helps.
MySQL does not currently support window functions, so over() will only yield syntax errors (or garbage, if it's accepted regardless).
MySQL Doesn't have window functions until the most recent release: MySQL 8 (release in April, 2018). MS SQL Server also accepts OVER clause.
The syntax is:
function(col1) OVER (PARTITION BY col2 ORDER BY col3)
Check out https://mysqlserverteam.com/mysql-8-0-2-introducing-window-functions/ for more examples.