ANSI SQL grouping by (Indian) financial year YTD - (last 5 years YTD) - mysql

Can anyone kindly point out how to group data until today (for last 5 years) for Indian fiscal (Apr-Mar). Say for example I need to extract 'field1','field2' from table 'aaa' from 01-Apr to today date for the last 5 years. My current solution can work safe until Dec, but later will run into error
SELECT
"Date",
"Daily data",
"ID",
"GA%",
"MA%"
FROM "table"
WHERE month("Date") >= 4
AND month("Date") <= month(today())
AND date("Date") < date(today())
Expected result format grouped by fiscal years:
FY-1 sum(daily data during the period) sum(GA) sum(MA)
FY-2 sum(daily data during the period) sum(GA) sum(MA)

SELECT
"Date",
"Daily data",
"ID",
"GA%",
"MA%"
FROM "table"
WHERE
"Date" between '2021-04-01' and '2021-11-29'
OR
"Date" between '2020-04-01' and '2020-11-29'
OR
"Date" between '2019-04-01' and '2019-11-29'
OR
"Date" between '2018-04-01' and '2018-11-29'
OR
"Date" between '2017-04-01' and '2017-11-29'

untested notepad scribble
SELECT
MIN(`Date`) AS StartDate
, MAX(`Date`) AS EndDate
, COUNT(ID) AS CountId
, SUM(`GA%`) AS `TotalGa%`
, SUM(`MA%`) AS `TotalMa%`
FROM `table` AS aaa
WHERE
(
(YEAR(`Date`) BETWEEN YEAR(CURRENT_DATE) - 4 AND YEAR(CURRENT_DATE) - 1)
OR
(YEAR(`Date`) = YEAR(CURRENT_DATE) AND MONTH(`Date`) <= 11)
OR
(YEAR(`Date`) = YEAR(CURRENT_DATE) - 5 AND MONTH(`Date`) > 3)
)
AND
(
MONTH(`Date`) NOT IN (12, 1, 2, 3)
OR
YEAR(`Date`) = YEAR(CURRENT_DATE)
)
GROUP BY CASE WHEN MONTH(`Date`) <= 3 THEN YEAR(`Date`) - 1
ELSE YEAR(`Date`) END
ORDER BY MIN(`Date`) DESC

Related

SELECT MAX MIN value of temperature CURRENT DAY but last YEARS from ALL history

I would like to ask you for help with SQL.
I have got database with where are 4 colums. ( time, temp, hum, press )
In this table are data from my meteo station.
Right now in this table are 110000 rows with records from last 3 years.
I want get MAX and MIN values of temp from all last years in same day like today.
I know how get all temp data from last years in same day but I do not know what next :-D
SELECT temp
FROM `table_name`
WHERE (
YEAR(time) < YEAR(CURDATE())
AND MONTH(time) = MONTH(CURDATE())
AND DAY(time) = DAY(CURDATE())
)
Sorry for my bad english.
Thank you
You can use date arithmetics and aggregation:
select min(temp) min_temp, max(temp) max_temp
from table_name
where
year(time) < year(current_date)
and month(time) = month(current_date)
and day(time) = day(current_date)
If you want the results by year:
select year(time) yr, min(temp) min_temp, max(temp) max_temp
from table_name
where
year(time) < year(current_date)
and month(time) = month(current_date)
and day(time) = day(current_date)
group by year(time)
order by year(time)

Query that shows the total profit in descending order for each month in 2010?

I am supposed to write a query that shows the total profit in descending order for each month in 2010.
So far, I have a query that shows the total profits in descending order for 2010 and I have a query that can extract each month, but I can't seem to connect the two.
select (SalesPrice - AcquisitionPrice) profit, datesold
from Transaction
where DateSold >= '10-jan-01' and DateSold <= '10-dec-31';
and:
select to_char(datesold, 'mon')
from transaction
group by to_char(datesold, 'mon')
Oracle Query:
SELECT TRUNC( datesold, 'MM' ) AS "Month",
SUM( SalesPrice - AcquisitionPrice ) AS profit
FROM Transaction
WHERE EXTRACT( YEAR FROM datesold ) = 2010
GROUP BY TRUNC( datesold, 'MM' )
ORDER BY TRUNC( datesold, 'MM' ) DESC
MySQL and Oracle Query:
SELECT EXTRACT( MONTH FROM datesold ) AS mnth,
SUM( SalesPrice - AcquisitionPrice ) AS profit
FROM Transaction
WHERE EXTRACT( YEAR FROM datesold ) = 2010
GROUP BY EXTRACT( MONTH FROM datesold )
ORDER BY EXTRACT( MONTH FROM datesold ) DESC

Select data between two dates exclude some days

I need to make query that selects data between two dates but exclude weekdays and some other days that are for example public holidays.
SELECT
`tblproduction`.`OperaterID`, `tblproduction`.`OperationID`,
SUM(`tblproduction`.`TotalProduced`) AS TotalProduced,
SUM(`tblproduction`.`TotalProducedOperator`) AS TotalProducedOp,
'Normal working day' AS DayType
FROM `tblproduction`
WHERE tblproduction.StartDateTime >= '2015-02-01 00:00:00' AND (tblproduction.StartDateTime <= '2015-02-28 23:59:59') AND tblproduction.OperaterID = 10
AND (DAYOFWEEK(tblproduction.StartDateTime) IN (1,7)) AND (DATE(tblproduction.StartDateTime) NOT IN (SELECT HolidayDate FROM tblholidays))
GROUP BY `tblproduction`.`OperaterID`, `tblproduction`.`OperationID`
UNION ALL
SELECT
`tblproduction`.`OperaterID`, `tblproduction`.`OperationID`,
SUM(`tblproduction`.`TotalProduced`) AS TotalProduced,
SUM(`tblproduction`.`TotalProducedOperator`) AS TotalProducedOp,
'Weekend' AS DayType
FROM `tblproduction`
WHERE tblproduction.StartDateTime >= '2015-02-01 00:00:00' AND (tblproduction.StartDateTime <= '2015-02-28 23:59:59') AND tblproduction.OperaterID = 10
AND (DAYOFWEEK(tblproduction.StartDateTime) NOT IN (1,7)) AND (DATE(tblproduction.StartDateTime) NOT IN (SELECT HolidayDate FROM tblholidays))
GROUP BY `tblproduction`.`OperaterID`, `tblproduction`.`OperationID`
For that purpose i have table with predefined dates that represents public holidays named tblHolidays. One of criteria in sql query is avoid counting pieces made during the holiday date. By running this query is steel includes those dates that are holidays. What should I change in query?
Maybe start with this...
SELECT p.OperaterID
, p.OperationID
, SUM(p.TotalProduced) TotalProduced
, SUM(p.TotalProducedOperator) TotalProducedOp
, CASE WHEN DAYOFWEEK(p.startdatetime) IN (1,7) THEN 'Normal working day' ELSE 'Weekend' END DayType
FROM tblproduction p
WHERE p.StartDateTime >= '2015-02-01 00:00:00' AND p.StartDateTime <= '2015-02-28 23:59:59'
AND p.OperaterID = 10
AND DATE(p.StartDateTime) NOT IN (SELECT HolidayDate FROM tblholidays)
GROUP
BY p.OperaterID
, p.OperationID
, CASE WHEN DAYOFWEEK(p.startdatetime) IN (1,7) THEN 'Normal working day' ELSE 'Weekend' END

How to select 6 months of data in MySQL, grouped between the 22nd and 21st of the next month

I have a table that contains the amount of data used each day, it looks something like this:
date | bytes
------------------
2014-01-1 | 12345
2014-01-2 | 56789
2014-01-3 | 78901
...
2014-02-1 | 12345
2014-02-2 | 56789
2014-02-3 | 78901
...
What I need to do is get the last 6 monthly totals, however the month must start on the 22nd day of the month and finish on the 21st day of the following month. For the current month it should start on the 22nd and finish today.
The best I can come up with is the following, the problem is - it is very messy and doesn't seem to give the correct result.
SELECT monthname(`date`),sum(`bytes`)
FROM `trafficDaily`
WHERE `date` between STR_TO_DATE( CONCAT( "22,", MONTH( NOW( ) )-6 , ",", YEAR( NOW( ) ) ) , "%d,%m,%Y" )
and STR_TO_DATE( CONCAT( "21,", MONTH( NOW( ) ) , ",", YEAR( NOW( ) ) ) , "%d,%m,%Y" )
group by month(DATE_SUB(`date`, INTERVAL 21 DAY))
order by `date`
Thank you in advance for your help.
You can do so by using user-defined variables to track the the change of month i.e in your case month starts from 21st
SELECT
MONTHNAME(STR_TO_DATE(group_day, '%m')) month_name ,
SUM(`bytes`) `sum`
FROM (
SELECT *,
#changemonth:= CASE
WHEN DAY(`date`) > 21
THEN #month
WHEN MONTH(`date`) <> #month
THEN #month
ELSE #month - 1
END group_day,
#month:= MONTH(`date`)
FROM
t ,(SELECT #changemonth:=0,
#month:= (SELECT MONTH(`date`) FROM t
WHERE `date` > NOW() - INTERVAL 6 MONTH ORDER BY `date` LIMIT 1) aa
) tt
WHERE `date` > NOW() - INTERVAL 6 MONTH
ORDER BY `date`
) a
GROUP BY group_day
Demo for last 3 months
Edit from comments for the case when January lies in last 6 month period
SELECT
MONTHNAME(
STR_TO_DATE(
CASE WHEN group_day < 1
THEN 12 ELSE group_day
END, '%m'
)
) month_name ,
SUM(`bytes`) `sum`
FROM (
SELECT *,
#changemonth:= CASE
WHEN DAY(`date`) > 21
THEN #month
WHEN MONTH(`date`) <> #month
THEN #month
ELSE #month - 1
END group_day,
#month:= MONTH(`date`)
FROM
t ,(SELECT #changemonth:=0,
#month:= (SELECT MONTH(`date`) FROM t
WHERE `date` > NOW() - INTERVAL 6 MONTH ORDER BY `date` LIMIT 1) aa
) tt
WHERE `date` > NOW() - INTERVAL 6 MONTH
ORDER BY `date`
) a
GROUP BY group_day
Demo with January
You have at least two options:
1st option
Create a calendar table and assign the 'business month' to each days. You can prepare your table for a long time period, then you can join to that table by date and you can do the grouping. If you have to do this calculation regularry, this is a good solution. (You can upgrade and use the calendar table to do several tasks)
2nd option
You can calculate the 'business month' by the date using the following query. (Please note, that I did not tested this query, so there could be typos).
SELECT
CASE
WHEN DAY(date) >= 22 THEN CONCAT(YEAR(date), '-', MONTH(date))
ELSE CONCAT(YEAR(date - INTERVAL 1 MONTH), '-', MONTH(date - INTERVAL 1 MONTH))
END AS m,
SUM(bytes)
FROM
log -- Use your table name instead :)
GROUP BY
CASE
WHEN DAY(date) >= 22 THEN CONCAT(YEAR(date), '-', MONTH(date))
ELSE CONCAT(YEAR(date - INTERVAL 1 MONTH), '-', MONTH(date - INTERVAL 1 MONTH))
END
You can adjust the calculation to your needs.

Retrieve data for specific months

MySQL Query is like this
SELECT MONTHNAME(access_date) as date,
DATE_FORMAT( access_date, '%m/%Y' ) as month_date ,
COUNT( log_id ) as total_count
FROM user_activity_log
WHERE dam_id = (
SELECT dam_id
FROM dam_content_details
WHERE content_type= '$content_type'
)
AND access_date >= last_day(NOW() - INTERVAL ($month) MONTH)
GROUP BY MONTH( access_date )
ORDER BY access_date ASC
i will pass the numbers like 1,2,3.... then its giving value for that month.
The problem i faced is it retrieving the data per 30 days,60 days like that. I want if i will write $month = '1; then it should return the current month data & previous month data starting from day 1.
My sample output - $month = 2
date month_date total_count
--------- ------------ -----------
December 12/2013 4
January 01/2014 1
I want for december it should calculate from 12/01/2013. 1st December 2013. Any idea how to solve it ?
You just have to remove = from >=.
Try this:
SELECT MONTHNAME(access_date) as date,
DATE_FORMAT( access_date, '%m/%Y' ) as month_date ,
COUNT( log_id ) as total_count
FROM user_activity_log
WHERE dam_id = (SELECT dam_id FROM dam_content_details WHERE content_type= '$content_type') AND
access_date > LAST_DAY(NOW() - INTERVAL (($month)+1) MONTH)
GROUP BY MONTH( access_date )
ORDER BY access_date ASC