How to select database rows by days ,month,years - mysql

How to select database rows by days ,month,years
I have table like this
id count generatedAt
1 130 2013-01-13 02:21:02
2 120 2013-01-08 04:15:06
3 89 2013-01-08 01:42:57
4 24 2012-11-25 05:31:43
5 3 2012-02-31 09:25:24
I would like to select the rows by day or month or year.
For example by day.
2-3 is same day so I need only
1,2,4,5
for example by month,1,2,3 is same month so I need only
1,4,5
for year I need only 1,4
How can I make it?
I am using doctorine2

You can do something like this . .
you can choose a date , month or specific year to select rows.
select * from TabeName
//for days
where DAY(myDate) = 20
//for month
MONTH(myDate) = 12
// for year
YEAR(myDate) = 2008

Related

MySQL Select data from table with dates between in reverse of interval 7 days

I have a MySQL requirement to select data from a table based on a start date and end date and group it by weekly also selecting the data in reverse order by date. Assume that, I have chosen the start date as 1st November and the end date as 04 December. Now, I would like to fetch the data as 04 December to 28 November, 27 November to 20 November, 19 November to 12 November and so on and sum the value count for that week.
Given an example table,
id
value
created_at
1
10
2021-10-11
2
13
2021-10-17
3
11
2021-10-25
4
8
2021-11-01
5
1
2021-11-10
6
4
2021-11-18
7
34
2021-11-25
8
17
2021-12-04
Now the result should be like 2021-12-04 to 2021-11-28 as one week, following the same in reverse order and summing the column value data for that week. I have tried in the query to add the interval of 7 days after the end date but it didn't work.
SELECT count(value) AS total, MIN(R.created_at)
FROM data_table AS D
WHERE D.created_at BETWEEN '2021-11-01' AND '2021-12-04' - INTERVAL 7 DAY ORDER BY D.created_at;
And it's also possible to have the last week may have lesser than 7 days.
Expected output:
end_interval
start_interval
total
2021-12-04
2021-11-27
17
2021-11-27
2021-11-20
34
2021-11-20
2021-11-13
4
2021-11-13
2021-11-06
1
2021-11-06
2021-10-30
8
2021-10-30
2021-10-25
11
Note that the last week is only 5 days depending upon the selected from and end dates.
One option to address this problem is to
generate a calendar of all your intervals, beginning from last date till first date, with a split of your choice, using a recursive query
joining back the calendar with the original table
capping start_interval at your start_date value
aggregating values for each interval
You can have three variables to be set, to customize your date intervals and position:
SET #start_date = DATE('2021-10-25');
SET #end_date = DATE('2021-12-04');
SET #interval_days = 7;
Then use the following query, as already described:
WITH RECURSIVE cte AS (
SELECT #end_date AS end_interval,
DATE_SUB(#end_date, INTERVAL #interval_days DAY) AS start_interval
UNION ALL
SELECT start_interval AS end_interval,
GREATEST(DATE(#start_date), DATE_SUB(start_interval, INTERVAL #interval_days DAY)) AS start_interval
FROM cte
WHERE start_interval > #start_date
)
SELECT end_interval, start_interval, SUM(_value) AS total
FROM cte
LEFT JOIN tab
ON tab.created_at BETWEEN start_interval AND end_interval
GROUP BY end_interval, start_interval
Check the demo here.

mysql find count of records each month and by referencing two dates

update: this can be done with python. here
i have a table like this:
event_id vendor_id start_date end_date
1 100 2021-01-01 2021-01-31
2 101 2021-01-15 2021-02-15
3 102 2021-02-01 2021-02-31
4 103 2021-02-01 2021-03-31
5 104 2021-03-01 2021-03-31
6 105 2021-03-01 2021-04-31
7 100 2021-04-01 2021-04-31
i would like an output like this: number of events based on month. but if the event between two or more months, it must be included in the count for each month. For example, The event in the second row (event_id=2) takes place in both January and February. Therefore, this event should be included in the total both in January and February.
output:
month total_event
2021-01 2 ---->> event_id=(1,2)
2021-02 3 ---->> event_id=(2,3,4)
2021-03 3 ---->> event_id=(4,5,6)
2021-04 2 ---->> event_id=(6,7)
Note: I wrote it to make the " --->> event_id= : " part better understood. i dont needed. i just need the month and the total_event.
i tried this query:
select date_format(start_date,'%Y-%m') as month,count(event_id) as total_event
group by date_format(start_date,'%Y-%m')
month total_event
2021-01 2
2021-02 2
2021-03 2
2021-04 1
but it counts only by start_date, so the numbers are missing.
Idea
To get the valid months list from the table
To calculate the event counts by event table's joining with the months
MySQL 8.0+
We can get the valid months list by Recursive.
Here is a full SQL. Assumed that your event table is c!
WITH RECURSIVE all_dates(dt) AS (
-- anchor
SELECT MIN(c.`start_date`) AS dt FROM c
UNION ALL
-- recursion with stop condition
SELECT dt + INTERVAL 1 MONTH
FROM all_dates WHERE dt + INTERVAL 1 MONTH <= (SELECT MAX(c.end_date) FROM c)
)
SELECT LEFT(dt, 7) AS `month`, COUNT(d.dt) AS total_event, GROUP_CONCAT(DISTINCT c.`event_id`) AS event_ids FROM all_dates d
INNER JOIN c ON LEFT(d.dt, 7) >= LEFT(c.start_date, 7) AND LEFT(d.dt, 7) <= LEFT(c.end_date, 7)
GROUP BY LEFT(dt, 7);

MySQL - Average ignoring Null and based on weekday

I´m trying to do some analysis in the following data
WeekDay Date Count
5 06/09/2018 20
6 07/09/2018 Null
7 08/09/2018 19
1 09/09/2018 16
2 10/09/2018 17
3 11/09/2018 24
4 12/09/2018 25
5 13/09/2018 24
6 14/09/2018 23
7 15/09/2018 23
1 16/09/2018 9
2 17/09/2018 23
3 18/09/2018 33
4 19/09/2018 22
5 20/09/2018 31
6 21/09/2018 17
7 22/09/2018 10
1 23/09/2018 12
2 24/09/2018 26
3 25/09/2018 29
4 26/09/2018 27
5 27/09/2018 24
6 28/09/2018 29
7 29/09/2018 27
1 30/09/2018 19
2 01/10/2018 26
3 02/10/2018 39
4 03/10/2018 32
5 04/10/2018 37
6 05/10/2018 Null
7 06/10/2018 26
1 07/10/2018 11
2 08/10/2018 32
3 09/10/2018 41
4 10/10/2018 37
5 11/10/2018 25
6 12/10/2018 20
The problem that I want to solve is: I want to create a table with the average of the 3 last same weekdays related to the day. But, when there is a NULL in the weekday, I want to ignore and do the average only with the remain numbers, not count NULL as an 0. I will give you an example here:
The date in this table is day/month/year :)
Ex: On day 12/10/2018, I need the average from
the days 05/10/2018; 28/09/2018; 21/09/2018. These are the last 3 same weekday(six) as 12/10/2018.
. Their values are Null; 29; 17. Then the result of this average must be 23, because I need to ignore the NULL, and not be 15,333.
How can I do this?
The count() function ignores nulls (i.e. does NOT increment if it encounters null) so I suggest you simply count the values then may contain the nulls you wish to ignore.
dow datecol value
6 21/09/2018 17
6 28/09/2018 29
6 05/10/2018 Null
e.g. sum(value) above = 46, and the count(value) = 2 so the average is 23.0 (and avg(value) will also return 23.0 as it also ignores nulls)
select
weekday
, `date`
, `count`
, (select (sum(`count`) * 1.0) / (count(`count`) * 1.0)
from atable as t2
where t2.weekday = t1.weekday
and t2.`date` < t1.`date
order by t2.`date` DESC
limit 3
) as average
from atable as t1
You could just use avg(count) in the query above, and get the same result.
ps. I do hope you do NOT use count as a column name! I also would suggest you do NOT use date as a column name either. i.e. Avoid using SQL terms as names.
SELECT WeekDay, AVG(Count)
FROM myTable
WHERE Count IS NOT NULL
GROUP BY WeekDay
Use IsNULL(Count,0) in your Select
SELECT WeekDay, AVG(IsNULL(Count,0))
FROM myTable
GROUP BY WeekDay
First off, you need to get the number of instances of that weekday in the data since you just need the last 3 same week days
create table table2
as
select
row_number() over(partition by weekday order by date desc) as rn
,weekday
,date
,count
from table
From here, you can get what you want. With you explanation, you don't need to filter out the NULL values for count. Just doing the avg() aggregation will simply ignore it.
select
weekday
,avg(count)
from table2
where rn in (1,2,3)
group by weekday

How to sum the value for each

I have table following :
ClientNUM PIECES DID
NEWAGENC 10 5
NEWAGENC 25 5
WAY 30 4
CHCAH 20 2
AVC 21 2
i want the Result that sum the value for each client as below
CleintNUM Pieces DID
NEWAGENC 35 5
WAY 30 4
CHCAH 20 2
AVC 21 2
My query
SELECT
CLIENTNUM,
DID,
PIECES,
GETDATE() AS CURRENTDATE,
SUM(PIECES)
FROM Mytable
GROUP BY CLIENTNUM, DISPID, PIECES
So how can i do the sum for each CLIENTNUM in my query Means DISTINCT For each client Pieces like NEWAGENC has value 10 and in second row 25 so the pieces will be 10+ 25 = 35
Don't group by PIECES if you want to aggregate it
SELECT CLIENTNUM,
DID,
PIECES,
GETDATE() AS CURRENTDATE,
SUM(PIECES)
FROM Mytable
GROUP BY CLIENTNUM, DISPID

How to calculate a moving 4 week average every week in MySQL

I have a table something like this.
count | date
------------------
1 2012-01-01
4 2012-01-01
5 2012-01-02
12 2012-01-03
7 2012-01-04
4 2012-01-05
19 2012-01-06
1 2012-01-07
etc...
I'm looking for a way to calculate the average count per week over the previous 4 week period for each week.
The results should be something like...
avg | yearweek
------------------
3 201201
5 201202
6 201203
1 201204
11 201205
3 201206
18 201207
12 201208
etc...
...where each yearweek is the weekly average over the past 4 yearweeks.
Getting the weekly averages is simple enough but how do I then get that over the past 4 yearweeks? And then how to do I do that as a rolling average? Am I better off just doing this in code?
While you could certainly do this in the code of your application, if you really need to do it in SQL, you could first create a table of results aggregated by week and then join it to itself to get the 4-week moving average.
In doing so, instead of storing the averages, I would store the sums and the number of days (1st or last week of year might not have 7 days - thinking of the edge cases). That way, you would avoid calculating unweighted averages when the denominators of averages are different.
So let's say you have a table "weekly_results", which has fields: yearweek, sumcount, numdays. You can now self-join to the last 4 weeks and get the sums and counts, and then calculate the averages from that:
SELECT yearweek, sum_cnt/sum_dys as avg_moving_4wk
FROM (
SELECT a.yearweek, sum(b.sumcount) as sum_cnt, sum(b.numdays) as sum_dys
FROM weekly_results a
join weekly_results b
on a.yearweek - b.yearweek <4 and a.yearweek - b.yearweek >=0
GROUP BY a.yearweek
) t1
GROUP BY yearweek