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

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)

Related

MySQL Group Grouped By Result

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;

MYSQL COUNT WITH 3 DISTINCT

Hi I have this VISITS table
What I want to achieve:
**affiliate_id** **unique visits count**
167 4
121 1
137 1
Special Condition is one IP can only be counted once per day for single affiliate_id.
So for visit_id 553 and 554, it can be only counted as one visits because both have same ip, same date and same affiliate_id.
From what I understand I need to group by ip, date and affiliate_id and count it, but not sure how to write the query.
Can you guys point me to some reference or insight to solve this problem?
Thanks in advance!
--
Update with link sample SQL:
https://dl.dropboxusercontent.com/u/3765168/tb_visits.sql
Based on your requirement i think you need the distinct ip per date and affiliate_id
select DATE(date), affiliate_id, count(distinct( ip))
from your_table
group by DATE(date), affiliate_id
If I understood correctly,
SELECT affiliate_id, count(*)
FROM (SELECT DISTINCT affiliate_id, ip, DAY(date)
FROM visits) AS q
GROUP BY affiliate_id;
What you are trying to do is group the number of unique or distinct ip's for a given affiliate_id so the only group by you need is the affiliate_id. The Unique hits are calculated using a count and to make then unique you add the DISTINCT key word
SELECT
affiliate_id, COUNT(DISTINCT ip) AS unique_visit_counts,
FROM tablename
GROUP BY affiliate_id
However since you want it by the day as well you might want to include a date clause such as:
DATE_FORMAT(date, "%y-%m-%d") AS `date`
Which will turn your date and time stamp into a day in the YY-MM-DD format.
If you group by that you can get a full list by day by affiliate_id using something like
SELECT
affiliate_id,
COUNT(DISTINCT ip) AS unique_visit_counts,
DATE_FORMAT(date, "%y-%m-%d") AS `date`
FROM tablename
GROUP BY `date`, affiliate_id
Or pick a specific date using something like
SELECT
affiliate_id,
COUNT(DISTINCT ip) AS unique_visit_counts,
FROM tablename
WHERE DATE_FORMAT(date, "%y-%m-%d") = '17-02-08'
GROUP BY affiliate_id

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

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