Have set up a query for my table where I would like to display certain reactions left within the previous weeks period, this works well when I write
SELECT *
FROM reactiondata
WHERE reaction_time > DATE_SUB(NOW(), INTERVAL 1 WEEK)
ORDER BY reaction_time ASC;
And also this query selects the unique promo ID fields and distinct usernames so you can see how many unique usernames have been sent which promo ID.
SELECT
reaction_promoID,
COUNT( DISTINCT reaction_username) AS reaction_username
FROM reactiondata GROUP BY reaction_promoID
However, I would like it so the second query works within a date range for the last week, like the first one does. When I add Where etc... to the query it does not work.
Any help hugely appeciated!
A+TS
SELECT reaction_promoID, COUNT( DISTINCT reaction_username) AS reaction_username
FROM reactiondata
WHERE reaction_time > DATE_SUB(NOW(), INTERVAL 1 WEEK)
GROUP BY reaction_promoID
I think this is time for HAVING clause:
http://www.w3schools.com/sql/sql_having.asp
SELECT reaction_promoID, COUNT( DISTINCT reaction_username) AS reaction_username
FROM reactiondata
GROUP BY reaction_promoID
HAVING reaction_time > DATE_SUB(NOW(), INTERVAL 1 WEEK)
Related
Im trying to get the number of customers that a company had each day for the last 7 days. But when I run my code I get the total of customers for the week and is just displaying the last order date.
SELECT order_date, COUNT(DISTINCT buyerid) as 'customers' from orders
WHERE
date(order_date) >= curdate() - 7
AND date(order_date) <= curdate()
Your code is able to run because it's not in 'full group by only' mode. That is because you're not aggregating the order_date, so you end up displaying only the last date and counting all the buyerids. This is almost never an expected result, I might say.
I would rewrite it like so:
SELECT order_date, COUNT(DISTINCT buyerid) as 'customers'
FROM orders
WHERE
order_date >= date_sub(curdate(), interval 1 week)
GROUP BY order_date
Now it will count the distinct buyerids in each day.
Also, curdate() - 7 doesn't seem to work so I rewrote it entirely, assuming order_date is of date type.
Mind you might miss results if its a datetime, and in that case compare it to now() or strip time entirely.
I don't get the meaning of the line AND date(order_date) = curdate(). It seems to be right only if you want today's sales.
I have a table, that pretty much looks like this:
users (id INT, masterId INT, date DATETIME)
Every user has exactly one master. But masters can have n users.
Now I want to find out how many users each master has. I'm doing that this way:
SELECT `masterId`, COUNT(`id`) AS `total` FROM `users` GROUP BY `masterId` ORDER BY `total` DESC
But now I also want to know how many new users a master has since the last 14 days. I could do it with this query:
SELECT `masterId`, COUNT(`id`) AS `last14days` FROM `users` WHERE `date` > DATE_SUB(NOW(), INTERVAL 14 DAY) GROUP BY `masterId` ORDER BY `total` DESC
Now the question: Could I somehow get this information with one query, instead of using 2 queries?
You can use conditional aggregation to do this by only counting rows for with the condition is true. In standard SQL this would be done using a case expression inside the aggregate function:
SELECT
masterId,
COUNT(id) AS total,
SUM(CASE WHEN date > DATE_SUB(NOW(), INTERVAL 14 DAY) THEN 1 ELSE 0 END) AS last14days
FROM users
GROUP BY masterId
ORDER BY total DESC
Sample SQL Fiddle
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)
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.
I have a table with columns: NAME, CHANGE_ID, and CHANGE_DATE, where each row constitutes a single change, the columns indicated who made the change(name), when it was made(timestamp), and an id for the change(integer).
I can retrieve a list of names sorted by those that have made the most changes(in the last month) with the following query:
SELECT
NAME AS name,
COUNT(DISTINCT CHANGE_ID) AS changes
FROM
CHANGE_TABLE
WHERE
DATE(CHANGE_DATE) > DATE(now() - INTERVAL 1 MONTH)
GROUP BY
name
ORDER BY
changes DESC
And I can retrieve a list of changes made per month in the last 10 months with the following query:
SELECT
DATE_FORMAT(CHANGE_DATE, '%Y-%m') AS date,
COUNT(DISTINCT CHANGE_ID) AS change_count
FROM
CHANGE_TABLE
WHERE
CHANGE_DATE > curdate() - INTERVAL 10 MONTH
GROUP BY
date
What I want is a query that will return the combined information of these queries: I want the names of the top change-makers and how many changes they have made each month for the last 10 months. I don't particularly care how the resulting table looks as long as the data is there. I have wracked my brain, but my SQL understanding is not great enough to solve the problem. Any help would be appreciated.
Have you tried grouping on date and name, something like:
SELECT
DATE_FORMAT(CHANGE_DATE, '%Y-%m') AS date,
COUNT(DISTINCT CHANGE_ID) AS change_count,
NAME
FROM
CHANGE_TABLE, (SELECT
NAME AS name,
COUNT(DISTINCT CHANGE_ID) AS changes
FROM CHANGE_TABLE
WHERE DATE(CHANGE_DATE) > DATE(now() - INTERVAL 1 MONTH)
GROUP BY name
ORDER BY changes DESC
) subq
WHERE CHANGE_DATE > curdate() - INTERVAL 10 MONTH AND change_table.name = subq.name
GROUP BY date, name