Invalid use of group function in Lag Function - mysql

I am brand new to SQL and have a fairly simple query but I keep getting the error "Invalid use of group function" when trying to use it. Here is my query:
select CreateDate as date,
count(*) as count,
lag(count(*), 1) OVER (order by CreateDate) as Previous
from contacts
Can someone explain why this would not work and how I can get it to function properly?

Your query raises error message:
ER_MIX_OF_GROUP_FUNC_AND_FIELDS: In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'test.contacts.createdate'; this is incompatible with sql_mode=only_full_group_by
This has nothing to do with lag(). Your query is just missing a group by clause:
select
CreateDate as date,
count(*) as count,
lag(count(*), 1) over(order by CreateDate) as previous
from contacts
group by createdate

Related

A query works fine in MySQL and gives 'in select clause is neither an aggregate nor in the group by clause' error in snowflake

MySQL query:
SELECT soc_pp_code, COUNT(soc_pp_code) AS count, rate
FROM subscriptions_history_sample_anonymized
GROUP BY soc_pp_code
ORDER BY COUNT(soc_pp_code) DESC
LIMIT 1;
Snowflake Query:
SELECT soc_pp_code, COUNT(soc_pp_code) AS count, rate
FROM subscriptions_history_sample_anonymized
GROUP BY 1
ORDER BY 2
LIMIT 1;
Error: SQL compilation error: error line 1 at position 49 'SUBSCRIPTIONS_HISTORY_SAMPLE_ANONYMIZED.RATE' in select clause is neither an aggregate nor in the group by clause.
Like the error message3 say, every column has to be in the group by or use an aggregation function like MIN for rate or what ever you need
SELECT soc_pp_code, COUNT(soc_pp_code) AS count, MIN(rate)
FROM subscriptions_history_sample_anonymized
GROUP BY 1
ORDER BY 2
LIMIT 1;

Questions for having clause and where clause

I have a very simple question. I am using Mysql bench, and i had a data which likes below:
dateordered_new orderstatus orders
2016-06-23 23:19:23 returned 8
2016-06-01 23:19:23 completed 12
2016-06-22 23:19:23 returned 9
2016-06-04 23:19:23 completed 27
...etc...
The question is simple, I want to show the amount of orders which has been returned in each month.
And here is my query:
select month(dateorderednew) as Month, sum(orders) as return_orders
from table_a
group by month
having orderstatus='returned;
Considering the difference between where clause and having clause, my syntax should be worked. However, the system told me that "Error Code: 1054. Unknown column 'orderstatus' in 'having clause'" And it was wired.
However, when I modified my query like this:
select month(dateorderednew) as Month, sum(orders) as return_orders
from table_a
where orderstatus='returned
group by month;
And it worked.
So, it was really confusing. I think having clause should follow by the group by statement. But I cannot answer why this case happened?
Do you guys have any idea for this?
In your situation, you should use a where clause:
select month(dateorderednew) as Month, sum(orders) as return_orders
from table_a
where orderstatus='returned'
group by month
Because you want to filter rows from the table before they are aggregated.
You only use having clause when you want to filter on an aggregate value, eg
select month(dateorderednew) as Month, sum(orders) as return_orders
from table_a
group by month
having sum(orders) > 10
However, mysql is flexible and allows you to use a having on a non-aggregate value.
HAVING is used to filter out results of aggregations, like MIN/MAX/AVERAGE, while WHERE is used to filter on non-aggregate columns.
For example, you can do this:
select month(dateorderednew) as Month, sum(orders) as return_orders
from table_a
WHERE orderstatus='returned'
group by month
having sum(orders) < 100
You have to replace the condition mentioned the having clause with where clause. Because having clause filter the data on aggregated group and where clause filter the data on whole record set.
Try the below SQL:
Select month(dateorderednew) as Month, sum(orders) as return_orders
from table_a
where orderstatus='returned
group by month;
A 'WHERE' clause filters on individual row values...
where colname > 0
or
where colname = 'sometext'
A 'HAVING clause filters on a group or aggregate of a row and comes after the 'group by' statement if there is one...
group by colname
having count(*) > 0
or
group by colname
having sum(colname) < 1

Select query inside a select query

I am running the following query on the table with multiple records having different quantity fields but the same id.
SELECT MIN( quantity )
FROM ( SELECT *
FROM `ready_for_delivery`
WHERE joborderid LIKE 00065
ORDER BY joborderid DESC ) a
GROUP BY quantity
It is returning all the values and not the minimum value. Any ideas why? Thanks in anticipation.
I think this is what you looking for:
SELECT MIN( quantity ) as 'Min' FROM ( SELECT * FROM `ready_for_delivery` WHERE joborderid LIKE 00065 ORDER BY joborderid DESC )a
If you are only after a single value, you should not be using a group by.
Definition for Group by:
A GROUP BY clause works on the rows returned by a query by summarizing identical rows into a single/distinct group and returns a single row with the summary for each group, by using appropriate Aggregate function in the
SELECT list, like
COUNT()
SUM()
MIN()
MAX()
AVG().

MySql, SELECT list is not in GROUP BY clause and contains nonaggregated column

I'm using MySql 5.7, and I'm getting an error in this query:
SELECT
COUNT(id) AS sales,
SUM(amount) AS total,
created
FROM
`payments`
WHERE status =1
GROUP BY MONTH(created);
if I change GROUP BY MONTH(created)
with:
GROUP BY created
then the error is gone. I dont have access to my.ini, to make changes to sql_mode.
Since you group month-wise, you shold output the months also
SELECT COUNT(id) AS sales,
SUM(amount) AS total,
MONTH(created)
FROM payments
WHERE status = 1
GROUP BY MONTH(created)
Otherwise MySQL has to pick a created value from the group. But you should define what to display.
Another possibility instead of outputting MONTH(created) would be a aggreagtion of the date like min(created) which would output the earliest date of each month.

MySQL query - using SUM of COUNT

This query:
SELECT COUNT(source) AS count
FROM call_details
GROUP BY source
HAVING count >1
Returns about 1500 (the number I'm looking for) results with only the count field. How could I also return the sum of all count fields? When I try
SELECT COUNT(source) AS count,
SUM(count) as total
FROM call_details
GROUP BY source
HAVING count >1
I get an 'Unknown column 'count' in 'field list' error.
And
SELECT COUNT(source) AS count,
SUM(COUNT(source)) as total
FROM call_details
GROUP BY source
HAVING count >1
gives me an 'Invalid use of group function'
Any ideas? I can do a mysql_num_rows($result) of the first set (to get the info I need) but I really want to do it through MySQL.
SELECT COUNT(count) FROM (SELECT COUNT(source) AS count
FROM call_details
GROUP BY source
HAVING count > 1) as A
You can't get a global total in a row-context. At the time the the COUNT() completes on any particular row, there's nothing to SUM, because the other rows haven't been calculated yet.
You'd have to run the SUM query first to get your individual stats, then sum manually in your script, or re-run the query with a surrounding SUM clause:
SELECT SUM(count) FROM (
SELECT original query here...
)
Try this
select mycount, sum(mycount) as sumcount
from
(SELECT COUNT(source) AS mycount FROM call_details GROUP BY source HAVING mycount >1) counttable
Assuming you are going to fetch all the results in the application anyway, I think the most efficient way would be to just sum it up in the application code.
Just simply remove the 'Group by' clause in the select query that counts
# first, get your counts by source
SELECT COUNT(source) AS count
FROM call_details
GROUP BY source
HAVING count >1
# then, get the overall total
SELECT COUNT(source) AS count
FROM call_details
HAVING count >1