Totals and Runningtotals with SQL "sum" and "over" Syntax - mysql

In my SQL table I have "country" and "we200326" columns. Column "we200326" contains only "1" or "NULL" entries.
I'm trying to get a total of all "1"s in column "we200326" and a total by country. I have written the following statement but it gives an error but I don't know what I did wrong (I'm very new at this):
SELECT country, we200326,
(SUM(we200326) OVER () AS Total)
(SUM(we200326) OVER (PARTITION BY country) AS CountryTotal)
FROM table_name
ORDER BY CountryTotal, Country;
The error I get is this:
MySQL said: Documentation
#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 'OVER () AS Total)
(SUM(we200326) OVER (PARTITION BY country) AS CountryTotal)
' at line 2
I have searched for similar errors and found several (each time was a simple syntax error like a space or comma or so) I tried several versions but could not resolve my problem when following those instructions. Any help would be appreciated.

Window functions are available in MySQL 8.0 only.
In earlier versions, one option is to use subqueries:
select
country,
wewe200326,
(select sum(we200326) from table_name) total,
(select sum(we200326) from table_name t1 where t1.country = t.country) country_total
from table_name t
order by country_total, country

Related

Window function syntax error at over clause

I'm solving a hackerrank SQL problem which you can see [here][1] and I have already solved it using some other method but I want to try the window function for the same, so I have run a basic query to understand the window function.
SELECT salary, SUM(salary) OVER (ORDER BY salary) AS running_total
FROM Employee;
but I got the below error.
ERROR 1064 (42000) at line 4: 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 salary) AS running_total FROM
employee' at line 2
I'm pretty confused why it's throwing an error.
P.S: the query I posted above is not solving the problem, it's just a try to understand the window function, if you can solve the whole problem using the window function and write it in the answer that also will help me learn more. if you need any more details please mention them in the comments.
Table name- Employee
columns:
employee_id-> integer
name-> string
months-> integer
salary-> integer
Mysql version - 8.0.20
[1]: https://www.hackerrank.com/challenges/earnings-of-employees/problem?isFullScreen=true
Most likely, your MySQL version is less than 8+, and therefore does not support window functions. Here is an alternative to your current query which should run on your MySQL version:
SELECT
salary,
(SELECT SUM(e2.salary) FROM Employee e2
WHERE e2.salary <= e1.salary) AS running_total
FROM Employee e1
ORDER BY salary;

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;

MySQL get calculated column and all column(*)

i have a table and i have columns. I want to get AGE column- it is creating (current date - year column data)- and whole columns like *.
I tried;
SELECT (YEAR(CURRENT_DATE) - YEAR(dateOfBirth)) as age , * FROM users
but it gives error:
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 users LIMIT 0, 25' at line 1
What should i write? Thank you!
use alias and TIMESTAMPDIFF function
SELECT u.*,
TIMESTAMPDIFF(YEAR, dateOfBirth, CURRENT_DATE) as age
FROM users u
'Use of an unqualified * with other items in the select list may produce a parse error. To avoid this problem, use a qualified tbl_name.* reference' - https://dev.mysql.com/doc/refman/8.0/en/select.html
This is ok
SELECT (YEAR(CURRENT_DATE) - YEAR(dateOfBirth)) as age, users.* FROM users

"group by desc" syntax error on mysql 8.0 which is fine on 5.7

The statement is like SELECT * FROM db.table group by id desc;
Would raise an error like
15:02:24 SELECT * FROM db.table group by id
desc LIMIT 0, 10 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 'desc LIMIT 0, 10' at line 1 0.00014
sec
on MySQL 8.0.13 in Ubuntu 18.04 Desktop 64bit
which would be fine on MySQL 5.7 in Windows or CentOS or Ubuntu.
I know basically, the select statement is like.
SELECT statement... [WHERE condition | GROUP BY `field_name(s)` HAVING condition] ORDER BY `field_name(s)` [ASC | DESC];
So is this 5.7's problem not to issue the error?
Or something more complicated on SQL standard?
I have the same issue, so for MySQL 8, I used the sql like that:
SELECT * FROM db.table
group by id
order by id desc
Taking from #P.Salmon's comment for the question.
If you look up the select statement in the manual
http://dev.mysql.com/doc/refman/5.7/en/select.html you will see
that up to 5.7 asc|desc are optional modifiers to the group by
statement which are no longer present from 8.0.and if you look at the
upgrade documentation
https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-sql-changes
This deprecation is documented.
Since this situation, #Linda Li's answer could be a good option.
This query makes no sense:
SELECT *
FROM db.table
GROUP BY id DESC;
You are doing an aggregation query. So (presumably), the table has multiple rows per id. Those are condensed down to one row. What values should be used for the other columns? It is sad that MySQL ever supported this syntax. So a welcome change is that ONLY_FULL_GROUP_BY is now the default.
A small hint is that using an aggregation query with no aggregation functions is suspicious.
Perhaps you want:
select id, min(col1), min(col2), . . .
from t
group by id;
Or more likely, you want a particular row, such as the "earliest" or "most recent", something like:
select t.*
from t
where t.createdAt = (select min(t2.createdAt) from t t2 where t2.id = t.id);

MySQL: Ordering of columns when using a wildcard with group by has odd behavior

What is the difference between these two MySQL statements?
Works:
select *, count(mycol) c from mytable group by mycol;
Doesn't work:
select count(mycol) c, * from mytable group by mycol;
The first statement works as I'd expect, while the second one gives me a syntax error. Why does the order matter?
I'm having trouble finding an answer from Google, because I'm not entirely sure if I'm asking the question correctly.
Edit:
Here's the sanitized error message. I'm using MySQL Workbench, if that's relevant.
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 mytable group by id' at line 1
Just alias the table and the syntax error will go away.
select count(t.id) c, t.* from mytable t group by id;
See this db fiddle.
It looks like MySQL allows bare (unqualified) * only as immediatly following SELECT. The following query also raises a syntax error :
select 1, * from mytable t;
The documentation prevents against using bare * combined with other items in the SELECT list :
A select list consisting only of a single unqualified * can be used as shorthand to select all columns from all tables.
Use of an unqualified * with other items in the select list may produce a parse error. To avoid this problem, use a qualified tbl_name.* reference.