MySQL MONTH returns wrong results - mysql

The following query didn't return correct results, because it returns results from "September" month but i need to get results from given month "August".
Is there something wrong in my query?
SELECT *
FROM table
WHERE YEAR(FROM_UNIXTIME(UNIX_date)) = '2012' AND
MONTH(FROM_UNIXTIME(UNIX_date)) = '08'
order by UNIX_date DESC
EDIT:
results that returned were like that:
post_id user_id UNIX_date
95319 12 1346475459
97370 5 1346474849
83527 25 1346474631
83526 51 1346473357
85929 12 1346471009
26677 29 1346462100
26839 12 1346432911
85927 12 1346411636

The month should not have a leading 0. So try 8 instead of 08.
You could also post a line of what is being returned so we can see how UNIX_date looks like.
reference: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_month

As written in the documentation http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_month, the DAY, MONTH and YEAR functions returns integer, thus values 1-12 (or zero) for the MONTH.

Related

SQL group by days interval

I have a sample table here with the following columns and sample records. I want to be able to sum my column cases using with a specific date range (the helper column).
I want to get my results this way:
Sum all cases WHERE date range is in between 2022-03-23 - 2022-04-01 and so on.
date range
Sum of Cases
2022-03-23-2022-04-01
5 (sample result only)
2022-03-24-2022-04-02
9 (sample result only)
The logic of the date range is always n - n9 days.
I 've tried this type of query but it does not work, it there a way for me to get this without have to use a query to create another column?
SELECT Date,
sum([QUERY 1]) as "Reports 7 days prev",
sum ([QUERY 2]) as "Reports 7 days after"
FROM REPORTS
GROUP BY Date
Data:
Date
BuyerID
Cases
Helper (Date Range)
4/1/2022
20001
2
2022-03-23-2022-04-01
4/1/2022
20001
1
2022-03-23-2022-04-01
4/2/2022
20002
3
2022-03-24-2022-04-02
4/5/2022
20003
5
2022-03-27-2022-04-05
4/7/2022
20004
6
2022-03-29-2022-04-07
4/7/2022
20005
9
2022-03-29-2022-04-07
Are you looking to get total cases for last X number of days? What does your initial data look like?
you can try something like:
Step 1: You aggregate all the cases for each date.
WITH CASES_AGG_BY_DATE AS
(
SELECT Date,
SUM(Cases) AS Total_Cases
FROM REPORTS
GROUP BY Date
),
Step 2: you aggregate the last 7 days rolling cases sum for each date
LAST_7_DAY_AGG AS
(
SELECT Date, SUM(Total_Cases) OVER(ORDER BY Date ASC ROWS BETWEEN 7 PRECEDING AND CURRENT ROW) AS sum_of_cases,
LAG(Date, 7) AS 7th_day
FROM CASES_AGG_BY_DATE
)
Step 3: create final output and concatenate date and 7th day before that
SELECT Date, CONCAT(Date, "-", 7th_day), sum_of_cases
FROM LAST_7_DAY_AGG;

count method returns different values depending on date in condition

I'm running a query that looks at the number of days where an activity for a record exists over the last three days (today included) in the database using the GroupBy gem to group them by day. Here is the full query:
Record.activities.where("created_at >= ?", 2.days.ago.beginning_of_day.in_time_zone).group_by_day(:created_at).count.count
2 days ago, I have 1 activity, yesterday I have 0 and today I have 2. This should return 2 (not 3, it's counting the days not the activities) but for some reason it returns 3. What's even stranger is that if I change 2.days.ago to 1.day.ago or 0.days.ago, it returns the correct value, 1. It ignores yesterday where there were no activities and only counts the day (today) where it recognised there was an activity.
If I remove the second .count, here's what it returns for 2.days.ago...
{Tue, 21 Nov 2017=>1, Wed, 22 Nov 2017=>0, Thu, 23 Nov 2017=>2}
and if I run it for 1.day.ago, I get...
{Thu, 23 Nov 2017=>2}
Here is the raw SQL for the 2.days.ago query..
SELECT COUNT(*) AS count_all, strftime('%Y-%m-%d 00:00:00 UTC', created_at)
AS strftime_y_m_d_00_00_00_utc_created_at
FROM "activities"
WHERE "activities"."goal_id" = ? AND (created_at >= '2017-11-21 00:00:00')
AND (created_at IS NOT NULL)
GROUP BY strftime('%Y-%m-%d 00:00:00 UTC', created_at)
After some more testing, I noticed it only ignores a day with 0 activities if the x in x.days.ago falls on the day with 0. If there is more than 1 day with 0 activities, it will ignore the first one as it should but then count the other days with 0 that come after...
Not sure what I'm missing here but would appreciate any help finding the issue.
Let me know if you need any more information.
You can use .having('count(activities.id) > 0') to ignore days with no activity
untested query below:
Record.activities
.select('count(activities.id) as count_all,date(activities.created_at) as day')
.where("created_at >= ?", 2.days.ago.beginning_of_day.in_time_zone)
.group('day').having('count_all > 0')
First of all your solution is not ok, because you need to make it in sql query (while you load all the data to ruby object and then sort them. It will be a bottle neck during scale). Just put the same thing to sql. I think this one should work:
Record.activities.where("created_at >= ? AND count_all > 0", 2.days.ago.beginning_of_day.in_time_zone).group_by_day(:created_at).count
Then about why you get 3 when you expect to get 2. Sql COUNT(*) returns number of rows. In your case you will always have 3 unique days, so 3 unique rows (group_by group them by their uniqueness). You must filter days with 0 count as I made in my query to filter rows, that have 0 in count, but still get counted
I've found a way to return the right result but still curious to know why that initial query returns those results.
Here is the query that works:
Record.activities.where("created_at >= ?", 4.days.ago.beginning_of_day.in_time_zone).group_by_day(:created_at).count.reject {|k,v| v == 0 }.count

Mysql group by 1-15 and 16-30/31 days of a month

I have a table with a lot of rows and i need to get the count of them grouped by ID and date bimonthly
For example
**ID Date**
15 2016/01/01
15 2016/01/04
15 2016/01/05
15 2016/01/22
15 2016/01/30
15 2016/02/01
15 2016/02/16
15 2016/03/01
15 2016/03/16
15 2016/03/22
Expected results:
**Count ID Date**
3 15 2016/01/01
2 15 2016/01/15
1 15 2016/02/01
1 15 2016/02/15
1 15 2016/03/01
2 15 2016/03/15
Currently i have this:
SELECT count(*) as '#', ID, from_unixtime(Date, '%Y-%m-%d') as 'Date'
FROM table
GROUP BY country,WEEK(FROM_UNIXTIME(Date))
ORDER BY Date
Which indeed groups by week but starting from the first input and so on (whici is not what i want but is as close as i have gotten)
EDIT: Changed the term to bimonthly
The 1st thru 15th and 16th thru 30/31 groups are not "biweekly". That grouping would be referred to as bimonthly. (I'd prefer the term "dimonthly" if that were a word.)
It's odd that you would want to return a value of the 15th, for the group that would not contain the 15th, rather than returning the 16th.
You could use expressions to get you the year and month, and then the 1st or 15th.
GROUP BY CONCAT(DATE_FORMAT(t.date,'%Y-%m-'),IF(DAY(t.date)<16,'01','15'))
+ INTERVAL 0 DAY
You could use the same expression in the SELECT list to return the date value.
(My personal preference would be to return a date value of yyyy-mm-16, rather than -15.)
Note that this won't return a "zero count" for a bimonthly period where there aren't any rows. A row for such a period would be "missing".
GROUP BY clauses can be arbitrary expressions, e.g.
GROUP BY (DAY(FROM_UNIXTIME(Date)) <= 15)
which would split things up into 1-15 and 16->

SQL - Why do the results from these 3 queries not add up?

Each of the 3 queries below spits out a series of months along with the number of quotes created for each month. Each quote in the database has a username associated with it which is the email address of the person.
I would assume that the total for any single month from QUERY 1, should be the number for that month in QUERY 2 PLUS the number for that month in QUERY 3. But they don't add up.
For example, I would have thought that I get something like:
QUERY NUMBER 1
Aug 2013 -> 2836
QUERY NUMBER 2
Aug 2013 -> 2500
QUERY NUMBER 3
Aug 2013 -> 325
so 2500 (QUERY NUMBER 2) + 325 (QUERY NUMBER 3) = 2825 rather than 2836 (QUERY NUMBER 1)
and I'm not sure why it doesn't give me 2836
Looking at the queries below, why doesn't QUERY 2 + QUERY 3 = QUERY 1?
There's only one line that changes:
WHERE created_by_username = 'sysadmin#mydomain.co.uk'
//QUERY NUMBER 1
SELECT DATE_FORMAT(created,'%b %Y'),
COUNT(DISTINCT username)
FROM view_all_quotes
GROUP BY DATE_FORMAT(created,'%b %Y')
ORDER BY created ASC
//QUERY NUMBER 2
SELECT DATE_FORMAT(created,'%b %Y'),
COUNT(DISTINCT username)
FROM view_all_quotes
WHERE created_by_username = 'sysadmin#mydomain.co.uk'
GROUP BY DATE_FORMAT(created,'%b %Y')
ORDER BY created ASC
//QUERY NUMBER 3
SELECT DATE_FORMAT(created,'%b %Y'),
COUNT(DISTINCT username)
FROM view_all_quotes
WHERE created_by_username <> 'sysadmin#mydomain.co.uk'
GROUP BY DATE_FORMAT(created,'%b %Y')
ORDER BY created ASC
Sorry I can't find the documentation to advise on formatting SQL in these posts.
Rows where the created_by_username is null will be excluded by both where clauses.
You can find these rows with:
select * from view_all_quotes where created_by_username is null
When I wrote the question I thought that the error was in the queries I'd created. However since writing it I have found that there was nothing wrong with the queries, and there weren't any records missing.
But there were a small number of usernames that were appearing in BOTH QUERY 2 and QUERY 3 (correctly) and so QUERY 1 was combining those usernames meaning that the values/results returned by QUERY 1 were smaller than QUERY 2 + QUERY 3. Hope that makes sense. Sorry for wasting anyone's time. I didn't realise when writing the question that the answer would be in the data that only I could see.
Thanks again.

mysql query to fetch the quarter month from table

Table name: activity
Field name: ProcessYM
I have mysql data like below.
ProcessYM
==========
201312
201311
201310
201309
201308
201307
201306
201305
201304
201303
201302
201301
201212
201211
201210
201209
201208
201207
201206
I want to fetch the result like below. I mean, the mysql query to fetch the every quarter of the year like 201312, 201309, 201306, 201303, 201212, 201209.. and so on.
Actual Output I expect
=======================
ProcessYM
201312
201309
201306
201303
201212
201209
201206
I have tried the below query, but it does not produce the expected result.
SELECT distinct `ActProcessYM` from `activity` where `ActProcessYM`%3=0 order by ActProcessYM desc
Output of above query
=====================
201312
201309
201306
201303
201210
201207
It is much appreciated for your smart reply.
You need to modulo of the month part only. Your query is implicitly casting your ProcessYM as an INT.
For example:
SELECT DISTINCT ProcessYM
FROM activity
WHERE RIGHT(ProcessYM,2)%3=0
ORDER BY ProcessYM DESC
fiddle
you should retrieve the last two digits from field value and do the logic as you are doing.
SELECT distinct `ActProcessYM` from `activity` where substring(ActProcessYM,5,2)%3=0 order by ActProcessYM desc
Here's a not-so-quick-and-dirty way of handing this date processing. I believe you're looking for a MySQL formula like this:
yyyymm = TRUNC_QUARTER(yyyymm)
That is, you are looking for a function that converts any yyyymm month notation into a notation that shows the month that ends the quarter in question.
Let's start with an expression that converts any particular DATETIME expression to the DATE of the beginning of the quarter.
DATE(CONCAT(YEAR(value),'-', 1 + 3*(QUARTER(value)-1),'-01'))
This takes a timestamp (e.g. '2011-04-20 11:15:01') and turns it into the date of the starting of the quarter. (e.g. '2011-04-01')
Having things in this date form is helpful because you can use them for date arithmetic. For example, you can get the last day of that quarter like this.
DATE(CONCAT(YEAR(value),'-', 1 + 3*(QUARTER(value)-1),'-01'))
+ INTERVAL 1 QUARTER - INTERVAL 1 DAY
Here's a writeup on all this: http://www.plumislandmedia.net/mysql/sql-reporting-time-intervals/
I've found it helpful to try to stick to the date datatype when processing time series data.
You need to separate out the month value before doing the modulo 3 (% 3). Doing a modulo 100 first will do it:
(ProcessYM % 100) % 3) = 0
or
mod(mod(ProcessYM,100),3) = 0
Try this,
SELECT distinct `ProcessYM` from `activity` where SUBSTRING(`ProcessYM`,5,2)%3=0 order by ProcessYM desc