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
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.
This seems really simple but i am unsure how to do it in mysql. i have a table of status changes of trades. what i would like to do is for each trade find the max date and therefore it's status in a given month. however i would like to count this trade for that month of the following month (the 1st), how can i do this in mysql?
i have below:
SELECT Trade_id,
max(Status_DateTime),
DATE_FORMAT(Status_DateTime,'%Y%m') monthyear,
DATE_ADD(DATE_FORMAT(Status_DateTime,'%Y%m'), interval 1 month) as MonthYear_increment
FROM tabletrades
WHERE trade_status in ('open','partial','partial01')
and Traade_id in('1234')
group by Trade_id,
DATE_FORMAT(Status_DateTime,'%Y%m'),
DATE_ADD(DATE_FORMAT(Status_DateTime,'%Y%m'), interval 1 month),
this does not really give me what i want though.. as the MonthYear_increment is null? i need this column as i need to be able to count my trade as the following 1st of the month.
how can i do this so that i get the following month of year as a column and i get this in the format year-month-day where day is 01. at present the date is 202005, i would ideally like 1st included too
Hmmm . . . You can get the last value for a month using row_number() and then add a month:
SELECT YEAR(status_datetime + interval 1 month),
MONTH(status_datetime + interval 1 month),
t.tradeid, t.status
FROM (SELECT t.*,
ROW_NUMBER() OVER (PARTITION BY year(Status_DateTime), month(Status_DateTime) ORDER BY Status_DateTime desc) as seqnum
FROM tabletrades
WHERE trade_status in ('open','partial','partial01') AND
Traade_id in ('1234')
) t
WHERE seqnum = 1
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)
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 CHANGES table with fields VALUE(integer) and CREATED_AT(timestamp). I want to know the total of the VALUE column grouped by each of the past 30 days (without making 30 queries).
So if yesterday there were records created with VALUEs of 10, -7, and 12; I would want a record returned with CREATED_AT = yesterday and TOTAL = 15.
Any help?
SELECT date(created_at) as CREATED_AT, sum(value) as TOTAL
FROM changes
WHERE created_at >= curdate() - interval 30 day
GROUP BY date(created_at);
Well, it slightly depends on what kind the timestamp is formatted in (SQL/ Unix/ etc). But this type of query might help you along:
SELECT
DATE_FORMAT(CREATED_AT, '%Y-%m-%d') ym,
COUNT(VALUE)
FROM foo
GROUP BY ym