Distinct values when already using count and group by - mysql

This is currently the SQL query I am using:
SELECT DAY(time), count(id)
FROM users
WHERE time >= now() - INTERVAL 7 DAY
GROUP BY DAY(TIME)
But it includes repeated email values. How can I get the count by day for only unique email address entries?
Thanks

Solution:
SELECT DAY(time), count(distinct email)
FROM userWHERE time >= now() - INTERVAL 7 DAY
GROUP BY DAY(TIME)

Related

MySQL query last 30 days sort by day

I have a query that I need to modify to use data variables to search counts for the last 30 days from today and group by date. My SQL server's /tmp/ directory (15GB) keeps filling up and the query fails.
SELECT DATE(`date_time`) AS DAY
, COUNT(DISTINCT(rcid)) AS COUNT
, COUNT(DISTINCT(tunnelip)) AS TAILS
FROM primarydata
WHERE SERVER LIKE"%VOE%"
AND DATE_SUB(NOW(), INTERVAL 30 DAY) and NOW()
GROUP BY DAY;
Can you run the query manually in a shell? Looks like you're almost there. It may be failing on the group by. At this point in the execution it doesn't know what column DAY is.
Try: GROUP BY DATE(date_time)
Instead of: GROUP BY DAY.
Your date check is missing the column name to test, and also missing the BETWEEN keyword between the two dates.
SELECT
DATE(`date_time`) AS DAY,
COUNT(DISTINCT (rcid)) AS COUNT,
COUNT(DISTINCT (tunnelip)) AS TAILS
FROM primarydata
WHERE SERVER LIKE "%VOE%"
AND date_time BETWEEN DATE_SUB(NOW(), INTERVAL 30 DAY) AND NOW()
GROUP BY DAY;
Try this:
SELECT
DATE(`date_time`) AS DAY,
COUNT(DISTINCT (rcid)) AS COUNT,
COUNT(DISTINCT (tunnelip)) AS TAILS
FROM primarydata
WHERE SERVER LIKE
"%VOE%" AND `date_time` BETWEEN DATE_SUB(NOW(), INTERVAL 30 DAY) AND NOW()
GROUP BY `date_time`;
Thanks all. I got t to work using CURDATE()
AND `date_time` BETWEEN CURDATE() - INTERVAL 30
SELECT
DATE(`date_time`) AS DAY,
COUNT(DISTINCT (rcid)) AS COUNT,
COUNT(DISTINCT (tunnelip)) AS TAILS
FROM primarydata
WHERE SERVER LIKE "%VOE%" AND `date_time` BETWEEN CURDATE() - INTERVAL 30 DAY AND NOW() GROUP BY DAY;

SQL count number of rows for 5 days and add to count_concat

I have a table that stores record each time a email is send through my app, Now I am trying to develop a statistic page for the app with highcharts. I am trying to tbl_template_log count number of entries for past 5 days and add these values to group_concat so i can feed the results into the graph.
my Query:
SELECT group_concat(count(tbl_template_log.templog_id)) as 'stats_data' FROM tbl_template_log
WHERE DATE(tbl_template_log.send_date) < DATE(NOW())
AND DATE(tbl_template_log.send_date) > DATE(NOW()) - INTERVAL 6 DAY
I get an SQL error:
1111 - Invalid use of group function
I assume this refers to the combination of group_concat() and count()
is there any way to construct a query which will do both count number of rows per day and add these values to group_concat....or perhaps some other way to do this operation...?
If you are trying to tbl_template_log count number of entries for past 5 days , then why not use as below using the group by. If you save date info as datetime then use date(tbl_template_log.send_date) as send_date and finally group by send_date
SELECT
tbl_template_log.send_date,
count(tbl_template_log.templog_id) as `stats_data`
FROM tbl_template_log
WHERE
DATE(tbl_template_log.send_date) < DATE(NOW())
AND
DATE(tbl_template_log.send_date) > DATE(NOW()) - INTERVAL 6 DAY
group by tbl_template_log.send_date
just try!
I think you need this :
SELECT
GROUP_CONCAT
(tbl_template_log.templog_id) AS stats_data
FROM
(
SELECT COUNT(stats_data)
FROM tbl_template_log
WHERE DATE(tbl_template_log.send_date) < DATE(NOW())
AND DATE(tbl_template_log.send_date) > DATE(NOW()) - INTERVAL 6 DAY
)test

match timestamp with date in MYSQL using PHP

I have a table
id user Visitor timestamp
13 username abc 2014-01-16 15:01:44
I have to 'Count' total visitors for a 'User' for last seven days group by date(not timestamp)
SELECT count(*) from tableA WHERE user=username GROUPBY __How to do it__ LIMIT for last seven day from today.
If any day no visitor came so, no row would be there so it should show 0.
What would be correct QUERY?
There is no need to GROUP BY resultset, you need to count visits for a week (with unspecified user). Try this:
SELECT
COUNT(*)
FROM
`table`
WHERE
`timestamp` >= (NOW() - INTERVAL 7 DAY);
If you need to track visits for a specified user, then try this:
SELECT
DATE(`timestamp`) as `date`,
COUNT(*) as `count`
FROM
`table`
WHERE
(`timestamp` >= (NOW() - INTERVAL 7 DAY))
AND
(`user` = 'username')
GROUP BY
`date`;
MySQL DATE() function reference.
Try this:
SELECT DATE(a.timestamp), COUNT(*)
FROM tableA a
WHERE a.user='username' AND DATEDIFF(NOW(), DATE(a.timestamp)) <= 7
GROUP BY DATE(a.timestamp);
i think it's work :)
SELECT Count(*)
from table A
WHERE user = username AND DATEDIFF(NOW(),timestamp)<=7

Count only where certain fields are unique? (Multiple GROUP BYs)

So I have a query which will count how many records there are for each date in the past 3 days, from my last question with the help of others I was able to come up with the following:
SELECT COUNT(*) AS dailyCount
FROM highscores
WHERE DATE(date) BETWEEN CURDATE() - INTERVAL 3 DAY AND CURDATE()
GROUP BY DATE(date)
The query does the following, for the past 30 days, it will get how many records there are on each individual day and that will be returned as dailyCount.
However what I want to do now is get it so that dailyCount will only count fields where username has not been counted before.
I have tried the following (adding username to the GROUP BYs):
SELECT COUNT(*) AS dailyCount
FROM highscores
WHERE DATE(date) BETWEEN CURDATE() - INTERVAL 3 DAY AND CURDATE()
GROUP BY DATE(date), username
However that did not give the expected result.
Credits to Wrikken
The following worked:
SELECT COUNT(DISTINCT username) AS dailyCount
FROM highscores
WHERE DATE(date) BETWEEN CURDATE() - INTERVAL 3 DAY AND CURDATE()
GROUP BY DATE(date)

How to count records as "0" that have value "0" when using WHERE x = 1

I have a table structure that looks like this:
I have a perfectly working query that counts how many records there have been per day the last 30 days. It looks likes this:
SELECT DATE(timestamp) AS date, COUNT(id) AS emails FROM 'emails WHERE timestamp >= now() - interval 1 month GROUP BY DATE(timestamp)
This outputs the following which is perfectly fine:
However, the next thing seems too difficult for me to imagine. Now I want to count how many records there have been per day the last 30 days BUT only where newsletter = 1.
I've tried to put a WHERE statement looking like this:
SELECT DATE(timestamp) AS date, COUNT(*) AS emails, nyhedsbrev FROM emails WHERE timestamp >= now() - interval 1 month AND nyhedsbrev = 1 GROUP BY DATE(timestamp)
... And that outputs the following:
The problem is, that its omitting the records with newsletter = 0 and there by I cant compare my first query against the new one, as the dates doesnt match. I know that is because I use WHERE newsletter = 1.
In stead of omitting the record I want a query that just puts a "0" from that date. How can I do this? The final query should be outputting this:
You should be able to simply use SUM() and IF() to get the desired output:
SELECT
DATE(timestamp) AS date,
COUNT(*) AS emails,
SUM(IF(nyhedsbrev > 0, 1, 0)) as nyhedsbrev_count
FROM
emails
WHERE
timestamp >= now() - interval 1 month
GROUP BY
DATE(timestamp)
SQLFiddle DEMO
Edit: You might even be able to simplify it, since it's a boolean, and simply use SUM(nyhedsbrev), but this REQUIRES that nyhedsbrev is only 0 or 1:
SELECT
DATE(timestamp) AS date,
COUNT(*) AS emails,
SUM(nyhedsbrev) as nyhedsbrev_count
FROM
emails
WHERE
timestamp >= now() - interval 1 month
GROUP BY
DATE(timestamp)
Possibly best to get a list of the dates and then left join that against sub queries to get the counts you require.
Something like this
SELECT Sub1.date, Sub2.emails, IFNULL(Sub3.emails, 0)
FROM (SELECT DISTINCT DATE(timestamp) AS date
FROM emails
WHERE timestamp >= now() - interval 1 month) Sub1
LEFT OUTER JOIN (SELECT DATE(timestamp) AS date, COUNT(id) AS emails
FROM emails WHERE timestamp >= now() - interval 1 month
GROUP BY DATE(timestamp)) Sub2
ON Sub2.date = Sub3.date
LEFT OUTER JOIN (SELECT DATE(timestamp) AS date, COUNT(*) AS emails
FROM emails
WHERE timestamp >= now() - interval 1 month AND nyhedsbrev = 1
GROUP BY DATE(timestamp)) Sub3
ON Sub1.date = Sub3.date
(you can probably optimise one subselect of this away, but I have done it in full to make it obvious how it is working)
Assuming newsletter is boolean 1/0 values then this might give you the table that you want:
SELECT DATE(timestamp) AS date, COUNT(*) AS emails, nyhedsbrev
FROM emails WHERE timestamp >= now() - interval 1 month GROUP BY DATE(timestamp),nyhedsbrev ;
Just adding another GROUP BY parameter.