MySQL Group Grouped By Result - mysql

I have a very simple table which consists of the following columns:
id | customer_id | total | created_at
I was running this query to get the results per day for the last ten days:
SELECT SUM(total) AS total, DATE_FORMAT(created_at, "%d/%m/%Y") AS date
FROM table
WHERE created_at BETWEEN "2017-02-20" AND "2017-03-01"
GROUP BY created_at
ORDER BY created_at DESC
This works fine, but I've just noticed that there's an issue with imported rows being duplicated for some reason so I'd like to update the query to be able to handle the situation if it ever happens again, in other words select one row instead of all when the date and customer id are the same (the total is also identical).
If I add customer_id to the group by that seems to work but the trouble with that is then the query returns a result per day for each customer when I only want the overall total.
I've tried a couple of things but I haven't cracked it yet, I think it will be achievable using a sub query and/or an inner join, I have tried this so far but the figures are very wrong:
SELECT
created_at,
(
SELECT SUM(total)
FROM table test
WHERE test.created_at = table.created_at
AND test.customer_id = table.customer_id
GROUP BY customer_id, created_at
LIMIT 1
) AS total
FROM table
WHERE created_at BETWEEN "2017-02-20" AND "2017-03-01"
GROUP BY created_at
ORDER BY created_at DESC
It's also a large table so finding a performant way to do this is also important.

First, are you sure that created_at is a date and not a datetime? This makes a big difference.
You can do what you want using two levels of aggregation:
SELECT SUM(max_total) AS total, DATE_FORMAT(created_at, '%d/%m/%Y') AS date
FROM (SELECT t.customer_id, t.created_at, MAX(total) as max_total
FROM table t
WHERE t.created_at BETWEEN '2017-02-20' AND '2017-03-01'
GROUP BY t.customer_id, t.created_at
) t
GROUP BY created_at
ORDER BY created_at DESC;

Related

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;

MySQL count results after MAX timestamp

I have two tables
mts
id
customer_id
created_at
mos
id
customer_id
created_at
I want to get the last time of an entry in mts and count the results of mos after MAX(mts.created_at). All should be GROUP BY customer_id.
I had the idea of a simple query like this, but this wont work.
SELECT id, created_at, COUNT(id)
FROM mos
WHERE created_at > (SELECT MAX(created_at) FROM mts)
GROUP BY customer_id
LIMIT 10
This SQL-Statement will just give you 1 single line in the result set (not matter what). Everything that is not part of an aggregate-function should by contained in GROUP BY.
Your SQL-Statement should look like this:
SELECT id, created_at, COUNT(id)
FROM mos
WHERE created_at > (SELECT MAX(created_at) FROM mts)
GROUP BY customer_id, id, created_at
LIMIT 10

mysql - want to group by two columns including by each day

I have the following mysql 5.5 query:
select count(original_url), original_url from page_views group by original_url order by count(original_url) desc;
but would also like to group by each day (like 2014-06-23) so that I can see which day has the most page_views per url. It's a rails app so there is a created_at. I was thinking something like:
select count(original_url), original_url, created_at from page_views group by original_url, created_at order by count(original_url) desc;
but that selects and groups by hour:min:sec and I just want it to be by day like YEAR-MONTH-DAY. How would I do that?
Try the Date function:
select count(original_url), original_url, created_at from page_views group by original_url, DATE(created_at) order by count(original_url)

Count and Group by Month name in railes

This is the code I have
MediaDownload.select("COUNT(*) AS count_all,MONTHNAME(created_at) AS created_at ").group('created_at').count
but instead of getting a sql(mysql) code like this :
SELECT COUNT(*) AS count_all, MONTHNAME(created_at) AS created_at FROM `media_downloads` GROUP BY created_at
I get this :
SELECT COUNT(*) AS count_all, created_at AS created_at FROM `media_downloads` GROUP BY created_at
What I am doing wrong. Is there any solutions to get what I want.
There is an excess count in your ActiveRecord query syntax, so the following one
MediaDownload.select("COUNT(*) AS count_all,MONTHNAME(created_at) AS created_at ").group('created_at')
generates sql query you want

Sql Query to count same date entries

All I want to count entries based on date.(i.e entries with same date.)
My table is
You can see 5th and 6th entry have same date.
Now, the real problem as i think is the same date entry have different time so i am not getting what I want.
I am using this sql
SELECT COUNT( created_at ) AS entries, created_at
FROM wp_frm_items
WHERE user_id =1
GROUP BY created_at
LIMIT 0 , 30
What I am getting is this.
I want entries as 2 for date 2012-02-22
The reason you get what you get is because you also compare the time, down to a second apart. So any entries created the same second will be grouped together.
To achieve what you actually want, you need to apply a date function to the created_at column:
SELECT COUNT(1) AS entries, DATE(created_at) as date
FROM wp_frm_items
WHERE user_id =1
GROUP BY DATE(created_at)
LIMIT 0 , 30
This would remove the time part from the column field, and so group together any entries created on the same day. You could take this further by removing the day part to group entries created on the same month of the same year etc.
To restrict the query to entries created in the current month, you add a WHERE-clause to the query to only select entries that satisfy that condition. Here's an example:
SELECT COUNT(1) AS entries, DATE(created_at) as date
FROM wp_frm_items
WHERE user_id = 1
AND created_at >= DATE_FORMAT(CURDATE(),'%Y-%m-01')
GROUP BY DATE(created_at)
Note: The COUNT(1)-part of the query simply means Count each row, and you could just as well have written COUNT(*), COUNT(id) or any other field. Historically, the most efficient approach was to count the primary key, since that is always available in whatever index the query engine could utilize. COUNT(*) used to have to leave the index and retrieve the corresponding row in the table, which was sometimes inefficient. In more modern query planners this is probably no longer the case. COUNT(1) is another variant of this that didn't force the query planner to retrieve the rows from the table.
Edit: The query to group by month can be created in a number of different ways. Here is an example:
SELECT COUNT(1) AS entries, DATE_FORMAT(created_at,'%Y-%c') as month
FROM wp_frm_items
WHERE user_id =1
GROUP BY DATE_FORMAT(created_at,'%Y-%c')
You must eliminate the time with GROUP BY
SELECT COUNT(*) AS entries, created_at
FROM wp_frm_items
WHERE user_id =1
GROUP BY DATE(created_at)
LIMIT 0 , 30
Oops, misread it.
Use GROUP BY DATE(created_at)
Try:
SELECT COUNT( created_at ) AS entries, created_at
FROM wp_frm_items
WHERE user_id =1
GROUP BY DATE(created_at)
LIMIT 0 , 30