Select records according to years's last day - mysql

I have table having 26 columns in which first 3 Columns are day,month,year. And rest of columns having some information that i have to show. Now i have to fetch records according to years's last day.
I have tried writing code.
select * from subscription_stats where year * 10000 + month * 100 + day = LAST_DAY(CONCAT(year,'-',month,'-',day))
But this will fetch records from last day of every month and i want last day of years.And also, When i dont have actual last day in records then this code will not work. So instead of LAST_DAY i want some functionality like MAX date in that month. How can i implement this functionality.

Is this what you want?
select *
from subscription_stats
where month = 12 and day = 31;
That returns the rows for December 31st.
If you don't have records for all days and you want the last day in the data:
select ss.*
from subscription_stats ss
where (ss.month, ss.day) = (select ss2.month, ss2.day
subscription_stats ss2
where ss2.year = ss.year
order by ss2.month desc, ss2.day desc
);

Related

How to select dates in a week from a week number in mySql

How can i select the rows with all dates in a given week number?
I have rows with dates like: 2019-01-05, 2019-01-08 etc
Now i would like to select all these dates thats in week 1, week 2 or week 5.
SELECT * FROM mytable
WHERE myDateColumn = WEEK(5)
Is this possible?
WHERE week(myDateColumn) in (1,2,5)
I found no other solution than use mySQL BETWEEN.
First find start and end date for the week number:
$dto = new DateTime();
$week_start = $dto->setISODate($chosenYear, $chosenWeek)->format('Y-m-d');
$week_end = $dto->modify('+6 days')->format('Y-m-d');
Then use BETWEEN
SELECT * FROM myTable WHERE date BETWEEN '$week_start' AND '$week_end'

create a ranking and statistics with repeated database records

Today I want to get a help in creating scores per user in my database. I have this query:
SELECT
r1.id,
r1.nickname,
r1.fecha,
r1.bestia1,
r1.bestia2,
r1.bestia3,
r1.bestia4
r1.bestia5
FROM
reporte AS r1
INNER JOIN
( SELECT
nickname, MAX(fecha) AS max_date
FROM
reporte
GROUP BY
nickname ) AS latests_reports
ON latests_reports.nickname = r1.nickname
AND latests_reports.max_date = r1.fecha
ORDER BY
r1.fecha DESC
that's from a friend from this site who helped me in get "the last record per user in each day", based on this I am looking how to count the results in a ranking daily, weekly or monthly, in order to use statistics charts or google datastudio, I've tried the next:
select id, nickname, sum(bestia1), sum(bestia2), etc...
But its not giving the complete result which I want. That's why I am looking for help. Additionally I know datastudio filters where I can show many charts but still I can count completely.
for example, one player in the last 30 days reported 265 monsters killed, but when I use in datastudio my query it counts only the latest value (it can be 12). so I want to count correctly in order to use with charts
SQL records filtered with my query:
One general approach for get the total monsters killed by each user on the latest X days and make a score calculation like the one you propose on the commentaries can be like this:
SET #daysOnHistory = X; -- Where X should be an integer positive number (like 10).
SELECT
nickname,
SUM(bestia1) AS total_bestia1_killed,
SUM(bestia2) AS total_bestia2_killed,
SUM(bestia3) AS total_bestia3_killed,
SUM(bestia4) AS total_bestia4_killed,
SUM(bestia5) AS total_bestia5_killed,
SUM(bestia1 + bestia2 + bestia3 + bestia4 + bestia5) AS total_monsters_killed,
SUM(bestia1 + 2 * bestia2 + 3 * bestia3 + 4 * bestia4 + 5 * bestia5) AS total_score
FROM
reporte
WHERE
fecha >= DATE_ADD(DATE(NOW()), INTERVAL -#daysOnHistory DAY)
GROUP BY
nickname
ORDER BY
total_score DESC
Now, if you want the same calculation but only taking into account the days of the current week (assuming a week starts on Monday), you need to replace the previous WHERE clause by next one:
WHERE
fecha >= DATE_ADD(DATE(NOW()), INTERVAL -WEEKDAY(NOW()) DAY)
Even more, if you want all the same, but only taking into account the days of the current month, you need to replace the WHERE clause by:
WHERE
MONTH(fecha) = MONTH(NOW())
For evaluate the statistics on the days of the current year, you need to replace the WHERE clause by:
WHERE
YEAR(fecha) = YEAR(NOW())
And finally, for evaluation on a specific range of days you can use, for example:
WHERE
DATE(fecha) BETWEEN CAST("2018-10-15" AS DATE) AND CAST('2018-11-10' AS DATE)
I hope this guide will help you and clarify your outlook.
This will give you number of monster killed in the last 30 days per user :
SELECT
nickname,
sum(bestia1) as bestia1,
sum(bestia2) as bestia2,
sum(bestia3) as bestia3,
sum(bestia4) as bestia4,
sum(bestia5) as bestia5
FROM
reporte
WHERE fecha >= DATE_ADD(curdate(), interval -30 day)
GROUP BY nickName
ORDER BY

Select records according to month's last day

I have table having 26 columns in which first 3 Columns are day,month,year. And rest of columns having some information that i have to show. Now i have to fetch records according to month's last day.
I have tried writing code.
select * from subscription_stats where year * 10000 + month * 100 + day = LAST_DAY(CONCAT(year,'-',month,'-',day))
But this will fetch records from last day of every month. When i dont have actual last day in records then this code will not work. So instead of LAST_DAY i want some functionality like MAX date in that month. How can i implement this functionality.
You want the last date in each month in your data. For this:
select s.*
from subscription_stats s
where s.day = (select max(s2.day)
from subscription_stats s2
where s2.year = s.year and s2.month = s.month
);
Although it would not make this query much simpler, you should be storing dates as dates in your table. That is, one date, not three separate columns for year/month/day.

mysql: slightest difference between days

i want to write a query which shows me the slightest difference between a given day of a month and the days in the tables.
select * from students where 5 = month(birthdate)
I want to search for the students who were born in May and now i want to get the slightest difference between a given day and the day of the birthday.
For example:
Alan 1980-05-03
Bob 1978-05-07
And i set the day to 8. The result should show me Bob. How should the query look like?
You could use:
SELECT *
FROM students
WHERE month(birthdate) = 5
ORDER BY ABS(DAY(NOW()) - DAY(birthdate))
LIMIT 1;
SqlFiddleDemo
When you compare only in one month range you could easily get difference between day in particular month.
Note: This won't handle ties.
Here you set the day, you choose all students with birthday that matches the birth date closest to the day you chose.
Set #Day = 5; -- your number
Select * from students
where month (birthdate)=5 -- set this to month
Having birthdate = (select min(birthdate) from students order by abs(#Day - dayofmonth(birth date)) desc limit 1);
Dayofmonth() returns the day (1-31) of the month for a given date.

How to get the record of employees who were joined in first quarter or first month

I want to retrieve the records of employees who were joined in first quarter or in the first month. I have tried this but am not getting the right answer...
SELECT * FROM table
WHERE DOJ(date_created) = DOJ(CURRENT_DATE - INTERVAL 1 MONTH)
Please help me with this!
Answering the question as clarified in a comment...
SELECT * FROM table
WHERE YEAR(table.doj) = 2015 AND QUARTER(table.doj) = 1
If instead you want "first quarter of prior year"...
SELECT * FROM table
WHERE YEAR(table.doj) = YEAR(CURRENT_DATE) - 1 AND QUARTER(table.doj) = 1
In either case, note that there's no code to include the first month, because that's part of the first quarter. However, if you wanted to make that explicit (at a slight performance hit), you could code it as follows...
SELECT * FROM table
WHERE YEAR(table.doj) = 2015 AND (QUARTER(table.doj) = 1
OR MONTH(table.doj) = 1)
If you run into performance problems because you have a lot of records but only an index on table.doj, you could also write the query over an explicit date range...
SELECT * FROM table
WHERE table.doj >= '2015-01-01' AND table.doj <= '2015-03-31'