I have table
Year Month Week Amount
-------------------------------------
2014 1 1 25501000,00
2014 1 2 118852000,00
2014 1 3 135764000,00
2014 1 4 153967000,00
2014 1 5 157648000,00
And I need select with one more row, that will be cumulative SUM of amount in each week:
Year Month Week ApvdAmtWeek SUMamount
---------------------------------------------------
2014 1 1 25501000,00 x1
2014 1 2 118852000,00 x1+x2
2014 1 3 135764000,00 x1+x2+x3
2014 1 4 153967000,00 x1+x2+x3+x4
2014 1 5 157648000,00 x1+x2+x3+x4+x5
Thank you for any help.
This may help you.
DECLARE #TAB TABLE (YEAR INT, MONTH INT, WEEK INT,AMOUNT BIGINT)
INSERT INTO #TAB VALUES
(2014,1,1,2550100000) ,
(2014,1,2,11885200000),
(2014,1,3,13576400000),
(2014,1,4,15396700000),
(2014,1,5,15764800000)
--Query:
SELECT Year,Month,Week,SUM(AMOUNT) ApvdAmtWeek FROM (
SELECT B.YEAR,B.MONTH,B.WEEK,A.AMOUNT
FROM #TAB A,#TAB B
WHERE A.WEEK <= B.WEEK) LU
GROUP BY YEAR,MONTH,WEEK
--Result:
One way, not pretty as there is no ID:
;with T as (
select row_number() over (order by year, Month, Week) rn, Year, Month, Week, Amount
from thetable
)
select T.rn, T.Year, T.Month, T.Week, sum(T2.Amount) from T
inner join (select
rn, Year, Month, Week, Amount from T
) T2 on T.rn >= T2.rn
group by T.rn, T.Year, T.Month, T.Week
order by T.rn
Related
I have sample dates in a table and what I need to get is each of the months between the start date and end date.
sample :
ID Startdate EndDate
1 01-01-2019 01-03-2019
2 01-08-2019 01-02-2020
I need to fetch months and year from these dates.
Desired output :
ID Dates
1 January 2019
1 February 2019
1 March 2019
2 August 2019
2 September 2019
2 October 2019
2 November 2019
2 December 2019
2 January 2020
2 February 2020
How cah I achieve this in MySQL and how to do increment or any loop kind of operation. On the query side I'm not getting any idea to move on this.
Here are a couple of ways to achieve this. The first will only work on MySQL 8+ and uses a recursive CTE to generate the months between StartDate and EndDate:
WITH RECURSIVE CTE AS (
SELECT ID, Startdate AS d, EndDate
FROM dates
UNION ALL
SELECT ID, d + INTERVAL 1 MONTH, EndDate
FROM CTE
WHERE d < EndDate
)
SELECT ID, DATE_FORMAT(d, '%M %Y') AS Dates
FROM CTE
ORDER BY ID, d
The second (which will run on any version of MySQL) uses a numbers table (in this case numbers from 0 to 99, allowing for a range of up to 99 months between StartDate and EndDate; if you need longer, adding more tables to the CROSS JOIN will increase that range by a factor of 10 for each table added) to generate the list of months difference, this is then JOINed to the original table so that the generated date Startdate + INTERVAL n.n MONTH is less than or equal to EndDate:
SELECT ID, DATE_FORMAT(Startdate + INTERVAL n.n MONTH, '%M %Y') AS Dates
FROM dates
JOIN (
SELECT n10.n * 10 + n1.n * 1 AS n
FROM (
SELECT 0 n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6
UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
) n10
CROSS JOIN (
SELECT 0 n UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3
UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6
UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9
) n1
) n ON Startdate + INTERVAL n.n MONTH <= EndDate
ORDER BY ID, Startdate + INTERVAL n.n MONTH
Having generated our list of dates, we format it using DATE_FORMAT and a format string of %M %Y. For both queries the output is:
ID Dates
1 January 2019
1 February 2019
1 March 2019
2 August 2019
2 September 2019
2 October 2019
2 November 2019
2 December 2019
2 January 2020
2 February 2020
Demo on dbfiddle
I have the entries of monthly dues like,
Table name : month_dues,
Columns:
customer_id,
due_date,
due_amount
These table have lot of due entries.
customer_id due_date due_amount
--------------------------------------
1 2018-12-01 100
1 2019-01-01 100
1 2019-02-01 100
1 2019-10-01 100
so, how to select pending due months from these record?
in my table customer 1 not paid dues for these months,
2019-03,2019-04,2019-05,2019-06,2019-07,2019-08, 2019-09
customer pay the due every month so
For select paid dues from table using,
SELECT customer_id, due_date, due_amount FROM month_dues where customer_id='1' where due_date>='2019-01-01' and due_date<='2019-10-18';
How to get pending due month and year using this table?
Which means, find month and year not in this record.
IF you are searching between the two dates
YOu can use this
select * from month_dues
where due_date between '2012-03-11 00:00:00' and '2012-05-11
23:59:00' && customer_id='1'
order by month_dues desc;
If you want to search the date(due_date) lower than today
SELECT * FROM month_dues WHERE due_date < CURDATE();
And you are refeering to the record that is not belong to the query you can find some NOT IN query
Like
`SELECT * FROM month_dues NOT IN ( select * from month_dues
where due_date between '2012-03-11 00:00:00' and '2012-05-11
23:59:00' && customer_id='1'
order by month_dues desc;
)`
So basically you need to validate your table against some kind of calendar, here is a simple solution that only works for the current year, maybe you can use it as a start or someone else could improve it
SELECT m.MONTH
FROM (SELECT 1 AS MONTH
UNION SELECT 2 AS MONTH
UNION SELECT 3 AS MONTH
UNION SELECT 4 AS MONTH
UNION SELECT 5 AS MONTH
UNION SELECT 6 AS MONTH
UNION SELECT 7 AS MONTH
UNION SELECT 8 AS MONTH
UNION SELECT 9 AS MONTH
UNION SELECT 10 AS MONTH
UNION SELECT 11 AS MONTH
UNION SELECT 12 AS MONTH) as m
WHERE m.MONTH NOT IN (SELECT MONTH(due_date)
FROM due_months
WHERE customer_id = 1
AND YEAR(due_date) = YEAR(CURDATE()))
AND m.MONTH < MONTH(CURDATE()) -- needs to be improved as well
I need to fetch data of the user's from created_date to till current data by month name and year with each month's total price.
Try 1:
SELECT MONTHNAME(start_time) month, YEAR(start_time) year, SUM(price) total
FROM table t1
WHERE t1.id= 33
GROUP BY YEAR(start_time), MONTH(start_time);
Output:
month year total
July 2019 360
September 2019 2160
October 2019 360
Expected output:
All month name and total will be 0 if data not exist.
month year total
Jan 2018 0
Feb 2018 0
...
Dec 2018 0
Jan 2019 0
Feb 2019 0
Mar 2019 0
Apr 2019 0
May 2019 0
Jun 2019 0
July 2019 360
Aug 2019 0
Sep 2019 2160
Oct 2019 360
Nov 2019 0
Dec 2019 0
After some RND I found one way and I have also tried that but now works.
Try 2:
SELECT IFNULL(SUM(ri.price),0) AS total, m.month
FROM (
SELECT 'Jan' AS MONTH
UNION SELECT 'Feb' AS MONTH
UNION SELECT 'Mar' AS MONTH
UNION SELECT 'Apr' AS MONTH
UNION SELECT 'May' AS MONTH
UNION SELECT 'Jun' AS MONTH
UNION SELECT 'Jul' AS MONTH
UNION SELECT 'Aug' AS MONTH
UNION SELECT 'Sep' AS MONTH
UNION SELECT 'Oct' AS MONTH
UNION SELECT 'Nov' AS MONTH
UNION SELECT 'Dec' AS MONTH
) AS m
LEFT JOIN table_u pu
ON MONTH(STR_TO_DATE(CONCAT(pu.created_date, '2019'),'%M %Y')) = MONTH(pu.created_date)
AND YEAR(pu.created_date) = '2019'
LEFT JOIN table ri
ON ri.id = pu.id
GROUP BY m.month
ORDER by 1+1;
Here is my refrence link.
Can anyone help me to fix this issue?
Thanks in advance.
Keep using LEFT JOIN (but only once) with a integer generator upto 12 (instead of month names, also easy using within the ORDER BY clause ), since you are able to get the month names by monthname() function. From your second query, I considered the current year. So, use :
SET #year=YEAR(NOW());
SELECT
MONTHNAME(STR_TO_DATE(concat(YEAR(NOW()),',',m.month,',1'),"%Y,%m,%d")) as month,
#year as year , SUM( COALESCE( pu.price, 0) ) as total
FROM (
SELECT rn as month
FROM
(
SELECT #rn := if(#i = #rn, #rn + 1, 1) as rn,
#i := #i+1
FROM information_schema.character_sets
JOIN (SELECT #i := 0, #rn := 0) as q_iter
LIMIT 12
) q
) AS m
LEFT JOIN table_u pu ON MONTH(pu.start_time) = m.month
AND YEAR(pu.start_time) = #year
AND ID = 33
GROUP BY m.month
ORDER by m.month;
Demo 1
Edit ( From the beginning of the year 2018 to the end of the current year ) :
SELECT MONTHNAME(
STR_TO_DATE(
CONCAT(m.year,',',if(mod(m.month,12)=0,12,mod(m.month,12)),',1'),"%Y,%m,%d")
)
as month,
year,
SUM( CASE WHEN YEAR(pu.start_time) = m.year AND MONTH(pu.start_time) = m.month
THEN
COALESCE( pu.price, 0)
ELSE
0
END ) as total
FROM
(
SELECT #i := if( #i = 12 , 1 , #i+1) as month,
#j := #j + 1,
#k:= if( #i = 1 and #j > 12, #k - 1, #k ) as year
FROM information_schema.character_sets
JOIN (SELECT #i := 0, #j := 0, #k:=YEAR(now())) as q_iter
) m
LEFT JOIN table_u pu ON MONTH(pu.start_time) = m.month
AND ID = 33
GROUP BY month, year
HAVING year >= ( SELECT MIN( YEAR(start_time) ) FROM table_u )
ORDER BY year, m.month;
Demo 2
If you have data in your table for all months, but just not for that id, then you can switch to conditional aggregation:
SELECT MONTHNAME(start_time) as month, YEAR(start_time) as year,
SUM(CASE WHEN t1.id = 33 THEN price ELSE 0 END) as total
FROM table t1
GROUP BY YEAR(start_time),MONTHNAME(start_time)
ORDER BY MIN(start_time);
Creating nonexistent year-month pairs by using user variables:
SELECT monthname(str_to_date(concat_ws(',',ym.month,'01,01'),'%m,%d,%y')) month
, ym.year year
, sum(price)
FROM table1 t1
RIGHT JOIN( SELECT #year := if(#month=12, #year+1, #year ) year
, #month := if(#month=12, 1 , #month+1) month
FROM table1
, ( SELECT #startYear := min(start_time)
, #endYear := year(now())
, #month := 12
, #year := min(start_time)-1
FROM table1
) t
WHERE (#year,#month) < (#endYear,12)
) ym
ON ym.year = year(t1.start_time)
AND ym.month = month(t1.start_time)
GROUP BY year(t1.start_time)
, month(t1.start_time)
The ym derived table is to provide year-month pairs starting on min year in table1 upto current year.
The innermost SELECT is for variables initialization.
You can try this:
SELECT to_char(start_time,'month')MONTH,to_char(start_time,'yyyy')YEAR,SUM(price)total
FROM TABLE_NAME
GROUP BY to_char(start_time,'month'),to_char(start_time,'yyyy')
Finally, I got the correct output which I want.
select
DATE_FORMAT(m1, '%M - %Y')
from
(
select
('2013-07-23')
+INTERVAL m MONTH as m1
from
(
select #rownum:=#rownum+1 as m from
(select 1 union select 2 union select 3 union select 4) t1,
(select 1 union select 2 union select 3 union select 4) t2,
(select 1 union select 2 union select 3 union select 4) t3,
(select 1 union select 2 union select 3 union select 4) t4,
(select #rownum:=-1) t0
) d1
) d2
where m1<=NOW()
order by m1
I want the count of records in every month and total count of records from start upto that month.
For ex.,
I have a table that looks like this:
#id,created#
1,'2016-01-01'
2,'2011-02-02'
3,'2011-02-09'
4,'2011-02-05'
5,'2011-03-07'
6,'2011-03-08'
How do I select and group these so the output is:
#Month, new, total#
Jan 2016, 1, 1
Feb 2016, 3, 4
Mar 2016, 2, 6
Thanks very much.
Here you go:
SELECT DATE_FORMAT(`created`,'%M %Y') AS month, COUNT(*) AS count,
(SELECT count(*) FROM test WHERE MONTH(created) <= MONTH(t.created)) AS total
FROM test t
GROUP BY MONTH(created);
Here's the SQL Fiddle.
Using single table read:
SELECT
CONCAT(LEFT(MONTHNAME(dt), 3), ' ', YEAR(dt)) month,
new,
#total:=#total + new total
FROM
(SELECT
created - INTERVAL DAY(created) - 1 DAY dt, COUNT(*) new
FROM
t
GROUP BY created - INTERVAL DAY(created) - 1 DAY
ORDER BY dt) t
CROSS JOIN
(SELECT #total:=0) t2
Demo
I have a table:
year val
---- ----
2013 4
2014 6
2014 2
2014 6
2015 1
2015 3
2016 7
is there a way to get the sum of the previous years for every year in the table?
the result should be like this:
2013 0
2014 4
2015 18
2016 22
2017 29
I tried something like this:
select year, sum(val) from
(select year, val from table ?????)
group by year
There should be an inner join somewhere maybe?
If you want old years only then use this query
SELECT DISTINCT year , ( SELECT SUM(val) FROM table as temp2 WHERE temp2.year < temp1.year ) as v FROM table as temp1
If you want to include year too then change temp2.year < temp1.year to <= , if you want to filter by years , then use comparison =
so
SELECT DISTINCT year , ( SELECT SUM(val) FROM table as temp2 WHERE temp2.year <= temp1.year ) as v FROM table as temp1
and
SELECT DISTINCT year , ( SELECT SUM(val) FROM table as temp2 WHERE temp2.year = temp1.year ) as v FROM table as temp1
but the latest could be easily done without subquery , just selecting year and sum(val) then group by year
Your question is a bit challenging because you want 0 for the first year:
select year,
( (#p := #p + sumval) - sumval) as cumeprev
from (select year, sum(val) as sumval
from table t
group by year
) t cross join
(select #p := 0) params
order by year;
Try
select year, #previous := #previous + sum(val)
from your_table
cross join (select #previous := 0) p
group by year
order by year