Questions for having clause and where clause - mysql

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

Related

SELECT date and then putting it into group

I am trying to select dates from my DB and then group it as months and years for example:
May 2019
June 2018
etc.
DB
-the date is type date
I have this code:
SELECT datum, count(*) FROM zapasy GROUP BY datum
Which makes it on each day, but I don't want that so I searched how to make it group as months and years, not just days
SELECT datum, count(*) FROM zapasy GROUP BY MONTH(datum), YEAR(datum)
and I came up with this, however, I am getting this stupid error
#1055 - Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'zapasy_db_test.zapasy.datum' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
And I have no idea what is wrong with the code
Please, give me some advice.
Thank you
You need to have the items you're grouping by in your select.
So
SELECT MONTH(datum), YEAR(datum), count(*) from ... group by MONTH(datum), YEAR(datum)
instead of datum, otherwise a date column you're selecting, will have a day in it, which you'd get from just datum, and that has nothing to do with the count and group and would be wrong, or the grouping wouldn't work at all.
I notice that your desired output is in this format May 2019 etc. You know that DATE datatype is like this, yyyy-mm-dd so if you really, really want to extract the month-year in that format, you can try the following:
SELECT DATE_FORMAT(datum, '%b %Y') AS 'Monthyear', COUNT(*)
FROM zapasy
GROUP BY Monthyear;

Mysql Select group by and without group by in one query

How can I select group by and without group by in one select query? I have a query like this
SELECT date, sum(total) as quotation_total
FROM suspended_bills
WHERE type='quotation'
GROUP BY YEAR(date), MONTH(date)
Here it is taking a group by year and month but I want a sum(total) without group by year and month. So I am able to get full sum(total) without a division of month and year.
This is not a duplicate entry as rollup is generating extra rows that I dont need, I only need the total of sum, so when I run this query with rollup it gave me more rows that is not desired. So all is wrong with roll up query.
In MySQL, the easiest way is a join or subquery:
select YEAR(sb.date), MONTH(sb.date), sum(sb.total) as quotation_total,
t.total_total
from suspended_bills sb cross join
(select sum(total) as total_totla
from suspended_bills
where type = 'quotation'
) t
where sb.type = 'quotation'
group by YEAR(sb.date), MONTH(sb.date), t.total_total;

Query SELECT DISTINCT count()

Hello there I have the following doubt I want to count how many times in a month I enter data.
My database is:
Date:
10/2010
10/2010
09/2010
08/2010
I have the following query.
SELECT DISTINCT (date)
FROM employee
WHERE date
IN (SELECT date
FROM employee
GROUP BY date
HAVING count( date ) >0)
ORDER BY date DESC;
This query gives me:
Date:
10/2017
8/2017
9/2017
But I want you to give me something like that.
Count | Date
2 | 10/2017
1 | 9/2017
1 | 10/2017
I hope I have explained my regards.
You're overcomplicating it; no subquery, or DISTINCT, needed.
SELECT `date`, count(*)
FROM `employee`
GROUP BY `date`
HAVING count(*) > 0
ORDER BY `date` DESC;
I am a little confused as to what reason you would have for the HAVING count() > 0 though; the only way something could have a zero count would mean it wasn't in the table (and therefore wouldn't show up anyway).
Other observations:
DISTINCT is not a function; enclosing the date in parenthesis in the SELECT clause has absolutely no effect. (Also, DISTINCT is almost never appropriate for a GROUPing query.)
COUNT(somefield) is the same as COUNT(1), COUNT(*). If you want the count of unique values you can do COUNT(DISTINCT somefield); but it wouldn't make sense to COUNT(DISTINCT groupingfield) as that would always result in 1.
The query you wrote is a bit complicated. Distinct and group by are doing the same thing for you here. When you do a group by count will automatically give you the count of grouped rows. Also you will have unique dates as well. Try this.
SELECT count(date), date
FROM employee
GROUP BY date
HAVING count( date ) >0
ORDER BY date DESC;

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().

How can i apply Multiple In clause in a single MySQL query

I have list of ids and corresponding creation dates
for Exmple :
1 2014-05-01
2 2014-07-01
3 2014-08-01
Need suggestion regarding writing a MySQL select statement which gives id details after corresponding creation date.
select id,count(*) from id_details where id IN(1,2,3) where resolved_at >(2014-05-01,2014-07-01,2014-08-01) group by id
The date condition for resolved_at column is not correct. Again, if you have two WHERE clause in your query, that as well not correct. You can's specify > condition in IN clause like you are trying. Your query should look like
select id,count(*)
from id_details
where id IN (1,2,3)
and (resolved_at >= '2014-05-01'
and resolved_at <= '2014-08-01')
group by id
I think you are just trying to use IN operator for resolved_at column like
select id,
count(*)
from id_details
where id IN (1,2,3)
and resolved_at IN ('2014-05-01','2014-07-01','2014-08-01')
group by id