I am new to Mysql,I wanted to use both sum(Max(column)) ?
I don't know why its impossible to use?
whereas count(Distinct(column)) is possible i.e using two aggregate functions together
The reason is SUM() and MAX() both are aggregate functions and these functions returning results by grouping their inputs across the table . While applying one aggregate function over another, it is something like grouping data over the result set of another grouping function and that is not allowed in SQL.
But in SQL Server, from 2008 version onwards introduced a new clause OVER() so that we can specify the grouping criteria in that over clause for that particular column.
In the case of DISTINCT which does not need any grouping and it pull the distinct record set over which we are applying the aggregate function. So that will work.
You can perform in the following way but if you are not using orther grouping columns then it always return 1 column so SUM(MAX(tot)) = MAX(tot) though we are not allow to do it in same place:
SELECT SUM(total) tot FROM (
SELECT
MAX(quantity) total
FROM deliveries) t;
DISTINCT is not an aggregate function. It's a keyword, a basic command.
In your case, when you're getting the MAX from a group you're getting a single value. SUM a single value makes no sense.
If you want so SUM the MAX values from all existing groups, you could try like this:
SELECT SUM(<column>)
FROM <table> t
WHERE NOT EXISTS
(
-- filter all max values from each group
SELECT 1
FROM <table> d
WHERE 1=1
AND d.<group_column1> = t.<group_column1>
AND d.<group_column2> = t.<group_column2>
...
AND d.<column> > t.<column>
)
Related
I'm trying to make an SQL query, that returns all the unique names and a sum of occurences for each name.
This is what I came up with, but it merely gets the sum of all names and not the sum of each name separately.
select distinct(etunimi) as etunimi,
(select count(distinct(etunimi)) as määrä from jasenet)
from jasenet;
Is this the right way to go when solving this problem or is there another way of achieving this? thank you.
If you group by a column then aggregate functions like count() apply to each group and not the complete result set.
select etunimi, count(*)
from jasenet
group by etunimi
That because you haven't reference the colomn from outerquery with subquery
So, it should be referenced like that :
select distinct etunimi,
(select count(*)
from jasenet j1
where j1.etunimi = j.etunimi
) as määrä
from jasenet j;
However, i would also suggest to use GROUP BY clause which is more efficient than correlated subquery.
in the below image I'm using
SELECT DISTINCT(name),date,reporting,leaving from attendance where date='2016-09-01
and I'm still getting repeating names. Why?
When using DISCTINCT, MySQL uses all columns as grouping factor. If you want group by only one column and get all corresponding column values, use GROUP BY instead
SELECT name, date, reporting, leaving FROM attendance GROUP BY name WHERE ...
Actually your all rows have distinct data apart from Name column if you want only distinct names then you can get it with help of Aggregate functions, you can use MIN or MAX as per your business requirement
SELECT Name,MAX(date),MAX(reporting),MAX(leaving)
FROM attendance
WHERE date='2016-09-01'
GROUP BY Name
Could someone explain why the following query throws an error, if I am trying to get the names of all customers along with the total number of customers?
SELECT name, COUNT(*)
FROM CUSTOMER
I know that selecting columns along with an aggregate function requires a GROUP BY statement containing all the column names, but I don't understand the logical principle behind this.
edit:
http://sqlfiddle.com/#!2/90233/595
I guess 'error' isn't quite right, but notice how the current query returns Allison 9 as the only result.
I don't understand why it doesn't return:
Alison 9
Alison 9
Alison 9
Alison 9
Jason 9
...
(This is a new answer based on the comment and looking at the fiddle.)
The issue here is how mysql handles aggregate functions -- which is a non-standard way and different then everyone else.
mysql lets you use aggregate functions (count() is an example of an aggregate function) without a group by. All (or most?) other sql implementations require the group by when you use count(*). When you have a group by you have to say the range in the group by (for example group by name). Also every column has to be in the range or the result of an aggregate function.
SINCE you don't have a range mysql assumes the whole table and since you have a column that is not the result of a aggregate function or in the range (in this case name) mysql does something to make that column the result of an aggregate function. I'm not sure if it is specified in mysql what it does -- lets say "max()". (Fairly sure it is max()). So the real sql that is getting executed is
SELECT ANY_VALUE(name), COUNT(*)
FROM CUSTOMER
Thus you only see one name.
mysql documentation - http://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html
After reading the above I see that mysql will use the default aggregate function ANY_VALUE() for columns which are not in the range.
If you just want the total number of customers on each row you could do this
SELECT DISTINCT NAME, COUNT(NAME) OVER () AS CustomerCount
FROM CUSTOMER
In this way you don't need the GROUP BY syntax. Under the covers it is probably doing the same thing as #GordonLinoff 's answer.
I added this because maybe it makes it clearer how group by works.
Select name, Count(*) as 'CountCustomers'
FROM CUSTOMER
Group by name
Order by name
Think of it as giving an instruction of which field to aggregate by. For example, if you had a field with the State of the Customer, you could group by State which would give a count of customers by state.
Also, note you can have multiple aggregate functions in the same select using the "over (partition by" construct.
If you want the names along with the total number of customers, then use a window function:
select name, count(*) as NumCustomersWithName,
sum(count(*)) over () as NumCustomers
from customer
group by name;
Edit:
You actually seem to want:
select name, count(*) over () as NumCustomers
from customer;
In MySQL, you would do this with a subquery:
select name, cnt
from customers cross join
(select count(*) as cnt from customers) x;
The reason your query doesn't work is because it is an aggregation query that returns exactly one row. When you use aggregation functions without a GROUP BY, then the query always returns exactly one row.
I have a table named forms with the following structure-
GROUP | FORM | FILEPATH
====================================
SomeGroup | SomeForm1 | SomePath1
SomeGroup | SomeForm2 | SomePath2
------------------------------------
I use the following query-
SELECT * FROM forms GROUP BY 'GROUP'
It returns only the first row-
GROUP | FORM | FILEPATH
====================================
SomeGroup | SomeForm1 | SomePath1
------------------------------------
Shouldn't it return both (or all of it)? Or am I (possibly) wrong?
As the manual states:
In standard SQL, a query that includes a GROUP BY clause cannot refer to nonaggregated columns in the select list that are not named in the GROUP BY clause. For example, this query is illegal in standard SQL because the name column in the select list does not appear in the GROUP BY:
SELECT o.custid, c.name, MAX(o.payment)
FROM orders AS o, customers AS c
WHERE o.custid = c.custid
GROUP BY o.custid;
For the query to be legal, the name column must be omitted from the select list or named in the GROUP BY clause.
MySQL extends the use of GROUP BY so that the select list can refer to nonaggregated columns not named in the GROUP BY clause. This means that the preceding query is legal in MySQL. You can use this feature to get better performance by avoiding unnecessary column sorting and grouping. However, this is useful primarily when all values in each nonaggregated column not named in the GROUP BY are the same for each group. The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate.
In your case, MySQL is correctly performing the grouping operation, but (since you select all columns including those by which you are not grouping the query) gives you an indeterminate one record from each group.
It only returns one row, because the values of your GROUP column are the same ... that's basically how GROUP BY works.
Btw, when using GROUP BY it's good form to use aggregate functions for the other columns, such as COUNT(), MIN(), MAX(). In MySQL it usually returns the first row of each group if you just specify the column names; other databases will not like that though.
Your code:
SELECT * FROM forms GROUP BY 'GROUP'
isn't very "good" SQL, MySQL lets you get away with it and returns only one value for all columns not mentioned in the group by clause. Almost any other database would not perform this query. As a rule, any column, that is not part of the grouping condition must be used with an aggregate function.
as far as mysql is concerned, I just solved my problem by hit & trial.
I had the same problem 10 minutes ago. I was using mysql statement something like this:
SELECT * FROM forms GROUP BY 'ID'; // returns only one row
However using the statement like the following would yeild same result:
SELECT ID FROM forms GROUP BY 'ID'; // returns only one row
The following was my solution:
SELECT ID FROM forms GROUP BY ID; // returns more than one row (with one column of field "ID") grouped by ID
or
SELECT * FROM forms GROUP BY ID; // returns more than one row (with columns of all fields) grouped by ID
or
SELECT * FROM forms GROUP BY `ID`; // returns more than one row (with columns of all fields) grouped by ID
Lesson: Donot use semicolon, i believe it does a stringtype search with colons. Remove colons from column name and it will group by its value. However you can use backtick escapes eg. ID
Thank you everyone for pointing out the obvious mistake I was too blind to see. I finally replaced GROUP BY with ORDER BY and included a WHERE clause to get my desired result. That is what I was intending to use all along. Silly me.
My final query becomes this-
SELECT * FROM forms WHERE GROUP='SomeGroup' ORDER BY 'GROUP'
SELECT * FROM forms GROUP BY `GROUP`
it's strange that your query does work
The above result is kind of correct, but not quite.
All columns you select, which are not part of the GROUP BY statement have to be aggregated by some function (list of aggregation function from the MySQL docu). Most often they are used together with numeric columns.
Besides this, your query will return one output row for every (combination of) attributes in the columns referenced in the GROUP BY statement. In your case there is just one distinct value in the GROUP column, namely "SomeGroup", so the output will only contain one row for this value.
Group by clause should only be required if you have any group functions, say max, min, avg, sum, etc, applied in query expressions. Your query does not show any such functions. Meaning you actually not required a Group by clause. And if you still use such clause, you will receive only the first record from a grouped results.
Hence output on your query is perfect.
Query result is perfect; it will return only one row.
For example:
SELECT MODE(field) FROM table
In another mode, what user-defined function can I use to get the most common value of a column?
I know I can do something like:
SELECT field, COUNT(*) as total FROM table GROUP BY field ORDER BY total DESC LIMIT 1
But I have to query other data in the same MySQL statement too, so I have to use a user-defined function.
Thank you.
Here's a link to MySQL's documentation on aggregate functions. It looks like they don't have anything for "mode", so I would say that your second query is probably your best shot.
MySQL doesn't support user-defined aggregate functions (PostgreSQL does, for what it's worth). You can't use a UDF to do what you want in MySQL.
You can do it for example by putting the mode-computation in a derived table subquery:
SELECT t.*
FROM (SELECT field AS mode, COUNT(*) as total FROM table
GROUP BY field ORDER BY total DESC LIMIT 1) AS m
JOIN table t ON m.mode = t.field;