5 day moving average of all items - mysql
below is my MYSQL table structure
ticker
_date
open
high
low
close
volume
below is sample data
ALMOND-I,2012-03-27,373.5000,395.0000,373.5000,380.2500,10
ALMOND-I,2012-03-31,391.0000,391.0000,386.0000,387.0000,5
ALMOND-I,2012-04-03,378.5000,386.0000,364.5000,378.5000,14
ALMOND-I,2012-04-11,380.0000,389.5000,370.7500,380.0000,3
ALMOND-I,2012-04-12,391.0000,391.0000,370.2500,380.7500,2
ALMOND-I,2012-04-16,392.0000,392.0000,392.0000,392.0000,1
ALMOND-I,2012-04-18,380.2500,380.2500,380.2500,380.2500,1
ALMOND-I,2012-05-02,371.0000,393.5000,371.0000,381.5000,6
ALMOND-I,2012-05-15,393.0000,393.0000,393.0000,393.0000,1
ALMOND-I,2012-05-21,416.7500,417.0000,393.0000,398.5000,10
ALMOND-I,2012-05-22,410.5000,410.5000,410.5000,410.5000,1
ALMOND-I,2012-05-30,435.2500,435.2500,435.2500,435.2500,1
ALUMINIUM-I,2012-05-22,110.8000,110.9500,110.2500,110.7000,4939
ALUMINIUM-I,2012-05-23,110.9000,111.4500,110.7500,111.2500,6996
ALUMINIUM-I,2012-05-24,111.0000,111.4500,109.9000,110.4500,7111
ALUMINIUM-I,2012-05-25,110.4500,110.6000,109.4000,109.7000,5020
ALUMINIUM-I,2012-05-26,109.6000,109.8500,109.6000,109.8000,116
ALUMINIUM-I,2012-05-28,109.4000,110.3000,109.3500,110.1500,2614
ALUMINIUM-I,2012-05-29,110.4500,111.0500,110.3000,110.8500,3956
ALUMINIUM-I,2012-05-30,110.9000,111.0500,110.1000,110.9500,5208
ALUMINIUM-I,2012-05-31,110.9500,111.7500,110.7500,111.3500,3553
ALUMINIUM-I,2012-06-01,111.1500,111.3000,108.7000,108.8500,7532
ALUMINIUM-I,2012-06-02,108.8000,108.8000,108.1000,108.2500,555
GOLD-I,2012-05-21,29018.0000,29174.0000,28956.0000,29035.0000,33330
GOLD-I,2012-05-22,29068.0000,29190.0000,28827.0000,29087.0000,45281
GOLD-I,2012-05-23,29026.0000,29084.0000,28831.0000,28969.0000,50523
GOLD-I,2012-05-24,29020.0000,29102.0000,28854.0000,28880.0000,45170
GOLD-I,2012-05-25,28841.0000,28937.0000,28748.0000,28902.0000,32176
GOLD-I,2012-05-26,28964.0000,28964.0000,28918.0000,28925.0000,1427
GOLD-I,2012-05-28,28901.0000,29055.0000,28882.0000,28965.0000,17158
GOLD-I,2012-05-29,28994.0000,29135.0000,28819.0000,28859.0000,39300
GOLD-I,2012-05-30,28845.0000,29154.0000,28755.0000,29117.0000,38733
GOLD-I,2012-05-31,29120.0000,29198.0000,29005.0000,29148.0000,22810
GOLD-I,2012-06-01,29130.0000,29871.0000,28765.0000,29724.0000,4753
GOLD-I,2012-06-02,29745.0000,29929.0000,29740.0000,29866.0000,337
SILVER-I,2012-05-21,54525.0000,54805.0000,53865.0000,54130.0000,66128
SILVER-I,2012-05-22,54187.0000,55119.0000,53873.0000,54392.0000,78147
SILVER-I,2012-05-23,54250.0000,54250.0000,53320.0000,53818.0000,87066
SILVER-I,2012-05-24,53999.0000,54785.0000,53980.0000,54317.0000,74940
SILVER-I,2012-05-25,54250.0000,54500.0000,53882.0000,54426.0000,61457
SILVER-I,2012-05-26,54481.0000,54535.0000,54465.0000,54479.0000,1535
SILVER-I,2012-05-28,54533.0000,54867.0000,54302.0000,54351.0000,33566
SILVER-I,2012-05-29,54448.0000,54885.0000,53790.0000,53964.0000,82448
SILVER-I,2012-05-30,53900.0000,54578.0000,53560.0000,54483.0000,87322
SILVER-I,2012-05-31,54377.0000,54465.0000,53820.0000,54110.0000,72225
SILVER-I,2012-06-01,54002.0000,54682.0000,52813.0000,54445.0000,107052
SILVER-I,2012-06-02,54530.0000,54610.0000,54451.0000,54487.0000,2371
WHEAT-I,2010-07-22,1276.9000,1276.9000,1228.2000,1247.9000,3
WHEAT-I,2010-07-23,1258.0000,1258.0000,1258.0000,1258.0000,2
WHEAT-I,2010-07-29,1245.0000,1245.0000,1245.0000,1245.0000,1
WHEAT-I,2010-07-30,1235.0000,1235.0000,1235.0000,1235.0000,1
WHEAT-I,2010-08-02,1245.0000,1245.0000,1240.0000,1242.5000,2
WHEAT-I,2010-08-04,1220.0000,1220.0000,1220.0000,1220.0000,1
WHEAT-I,2010-08-05,1240.0000,1240.0000,1232.0000,1237.3000,3
WHEAT-I,2011-03-19,1218.9000,1218.9000,1218.9000,1218.9000,1
WHEAT-I,2011-03-21,1182.3000,1182.3000,1182.3000,1182.3000,1
WHEAT-I,2011-03-25,1151.5000,1151.5000,1151.5000,1151.5000,2
WHEAT-I,2011-04-19,1160.0000,1160.0000,1149.5000,1152.3000,4
WHEAT-I,2011-04-28,1170.0000,1195.0000,1170.0000,1182.5000,4
ZINC-I,2012-05-21,103.8000,104.7500,103.8000,104.7000,13197
ZINC-I,2012-05-22,104.7000,105.6000,104.3000,105.5000,14996
ZINC-I,2012-05-23,105.3500,105.4500,104.5000,105.0000,16656
ZINC-I,2012-05-24,104.8000,105.3000,104.2000,104.6500,12688
ZINC-I,2012-05-25,104.6000,105.3000,104.1500,104.9500,12523
ZINC-I,2012-05-26,104.9000,105.0000,104.8000,104.9500,215
ZINC-I,2012-05-28,105.0000,105.5500,104.9000,105.2500,7387
ZINC-I,2012-05-29,105.6000,106.7000,105.4000,106.6000,14092
ZINC-I,2012-05-30,106.3000,106.5000,105.4500,106.3000,11983
ZINC-I,2012-05-31,106.0500,107.4000,105.7500,107.1500,5936
ZINC-I,2012-06-01,105.6500,105.7500,103.7000,104.6500,15231
ZINC-I,2012-06-02,104.5500,104.6500,104.2500,104.4000,551
i want to calculate moving average CLOSE of each item for last 5 dates
example for zinc average ClOSE on 2012-06-02 would be (104.4000+104.6500+107.1500+106.3000+106.6000)/5=105.82
i wrote a query
SELECT x.ticker , AVG( x.close), x._date
FROM
(
SELECT t.ticker , t.close,t._date
FROM mcx_eod_data t
ORDER BY t._date DESC
) x
GROUP BY x.ticker
it gives me average for i think the entire close from start to end of the particular ticker
so i did some Research and added limit statement and modified my query
SELECT x.ticker , AVG( x.close), x._date
FROM
(
SELECT t.ticker , t.close,t._date
FROM mcx_eod_data t
ORDER BY t._date DESC limit 5
) x
GROUP BY x.ticker
but now it fetches data for only 5 tickers
i want to achieve is average of close of last 5 dates for all tickers
Replace the order and limit with a where clause:
WHERE t._date >= DATE_SUB(NOW(), INTERVAL 5 DAY)
Related
Get previous day inserted data from table using MYSQL
I want to get data of previous day which inserted in table SELECT * FROM tbl_stockpricemaster AS sm WHERE DATE(sm.inserted_on)=DATE(NOW()- INTERVAL 1 DAY) AND sm.stock_keyvalue='positive' GROUP BY sm.stock_id ORDER BY sm.stock_difprice DESC LIMIT 5; This is my query but the problem is that when there is no data inserted on previous day then it show blank but i want to show the last inserted record
You will have to find out which date is the previous date This can be done using this statement: SELECT MAX(inserted_on) FROM tbl_stockpricemaster WHERE inserted_on < DATE(NOW()) So, changing your query to this should solve your problem: SELECT * FROM tbl_stockpricemaster AS sm WHERE DATE(sm.inserted_on)=(SELECT MAX(inserted_on) FROM tbl_stockpricemaster WHERE inserted_on < DATE(NOW()) ) AND sm.stock_keyvalue='positive' GROUP BY sm.stock_id ORDER BY sm.stock_difprice DESC LIMIT 5;
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
MySQL order by launch date within 3 months from now first, then launch date desc
I have got a table like the following. The select order needs to show closest launch date from now first(it is more urgent), then launch date desc. Say current date is 17-11-2017 tblProduct 01-02-2016 09-05-2015 03-11-2017 30-11-2017 02-01-2018 09-06-2018 The output order should be 30-11-2017 02-01-2018 09-06-2018 03-11-2017 09-05-2015 01-02-2016 The top 2 are within 3 months from now, so are shown first(between the 2 results, 30-11-2017 is closer from now so shown first). What's the mysql query?
I'm sure not the most elegant way, but this could help you http://sqlfiddle.com/#!9/2a6eca/1 SELECT *, IF(mydate BETWEEN NOW() AND DATE_ADD( NOW() , INTERVAL +3 MONTH) , 1, 0) as `dateInRange` FROM `demo` ORDER BY `dateInRange` DESC, CASE WHEN `dateInRange` = 1 THEN `mydate` END ASC, CASE WHEN `dateInRange` = 0 THEN `mydate` END DESC What this does is adds another column dateInRange to the selection (and sets it to 1 if date is between now and 3 monts from now. Then in the order by part we first sort by this column (making sure all the dates that are in the 3 months range are on the top), and when this column is equal to 0, then we sort by the actual date ascending. If this column is 0 we sort by dates descending. This code does what you would like, but there must be a more elegant way to go about this.
Select last row in MySQL statment
here is the mysql statement : SELECT MAX(`history_card`.`PART_NUMBER`) AS `PART_NUMBER`, `history_card`.`SERIAL_NUMBER`, MAX(`history_card`.`POSITION`) AS `POSITION`, MAX(`history_card`.`RELEASE_DATE_TO_AIRCRAFT`) AS `RELEASE_DATE_TO_AIRCRAFT`, MAX(`history_card`.`DATE_OFF_AIRCRAFT`) AS `DATE_OFF_AIRCRAFT`, MAX(`history_card`.`LAST_CAP_CHECKED_DATE`) AS `LAST_CAP_CHECKED_DATE`, MAX(`history_card`.`DUE_CAP_CHECK_DATE`) AS `DUE_CAP_CHECK_DATE`, MAX(`history_card`.`JOB_REMARKS`) AS `JOB_REMARKS`, MAX(`history_card`.`TSO`) AS `TSO`, MAX(`history_card`.`BO_NUMBER`) AS `BO_NUMBER`, MAX(`history_card`.`REPAIR_ORDER_NUMBER`) AS `REPAIR_ORDER_NUMBER`, MAX(`history_card`.`LAST_OVERHAULED_DATE`) AS `LAST_OVERHAULED_DATE`, MAX(`history_card`.`DUE_OVERHAUL_DATE`) AS `DUE_OVERHAUL_DATE`, MAX(`history_card`.`REFRESHER_DATE`) AS `REFRESHER_DATE`, MAX(`history_card`.`REFRESHER_DONE`) AS `REFRESHER_DONE`, MAX(`history_card`.`GRN_ISSUE_DATE`) AS `GRN_ISSUE_DATE`, MAX(`history_card`.`WORKSHEET`) AS `WORKSHEET`, MAX(`history_card`.`ADDITIONAL_ATTACHMENT`) AS `ADDITIONAL_ATTACHMENT`, MAX(`history_card`.`GRN`) AS `GRN` FROM `history_card` GROUP BY `history_card`.`SERIAL_NUMBER` HAVING (((MAX(`history_card`.`DUE_CAP_CHECK_DATE`)) BETWEEN NOW() AND DATE_SUB(NOW(), INTERVAL -60 DAY) )) ORDER BY MAX(`history_card`.`DUE_CAP_CHECK_DATE`) DESC; Instead of MAX() I need to select the last row , meaning that the ID DESC has to be selected and limited to 1 record : ORDER BY id DESC LIMIT 1 but right now It is returning the max value , Coz I'm converting this query from MS , MS used LAST() function to get the last record by in mysql I need a similar solution for MySQL
If I understood the problem correctly, something on these lines should work: SELECT `history_card`.`SERIAL_NUMBER`, `history_card`.`PART_NUMBER` AS `PART_NUMBER`, `history_card`.`POSITION` AS `POSITION`, `history_card`.`RELEASE_DATE_TO_AIRCRAFT` AS `RELEASE_DATE_TO_AIRCRAFT`, `history_card`.`DATE_OFF_AIRCRAFT` AS `DATE_OFF_AIRCRAFT`, `history_card`.`LAST_CAP_CHECKED_DATE` AS `LAST_CAP_CHECKED_DATE`, `history_card`.`DUE_CAP_CHECK_DATE` AS `DUE_CAP_CHECK_DATE`, `history_card`.`JOB_REMARKS` AS `JOB_REMARKS`, `history_card`.`TSO` AS `TSO`, `history_card`.`BO_NUMBER` AS `BO_NUMBER`, `history_card`.`REPAIR_ORDER_NUMBER` AS `REPAIR_ORDER_NUMBER`, `history_card`.`LAST_OVERHAULED_DATE` AS `LAST_OVERHAULED_DATE`, `history_card`.`DUE_OVERHAUL_DATE` AS `DUE_OVERHAUL_DATE`, `history_card`.`REFRESHER_DATE` AS `REFRESHER_DATE`, `history_card`.`REFRESHER_DONE` AS `REFRESHER_DONE`, `history_card`.`GRN_ISSUE_DATE` AS `GRN_ISSUE_DATE`, `history_card`.`WORKSHEET` AS `WORKSHEET`, `history_card`.`ADDITIONAL_ATTACHMENT` AS `ADDITIONAL_ATTACHMENT`, `history_card`.`GRN` AS `GRN` FROM `history_card` JOIN ( SELECT MAX(`history_card`.`ID`) ID, `history_card`.`SERIAL_NUMBER` FROM `history_card`, WHERE `history_card`.`DUE_CAP_CHECK_DATE` BETWEEN NOW() AND DATE_SUB(NOW(), INTERVAL -60 DAY) GROUP BY `history_card`.`SERIAL_NUMBER` ) HC ON `HC`.`ID`=`history_card`.`ID` AND `HC`.`SERIAL_NUMBER`=`history_card`.`SERIAL_NUMBER`
SELECT TOP 1 * FROM .... ORDER BY ID DESC should get you your last record.
mysql most popular page in 5 minute intervals
I have a MySQL table "page" that contains fields "page_name" and "page_timestamp". The table stores page and times requests that were made on a website. I'm trying to write a query that gives me the most hit page for every 5 min period. Output like Time Page Hits 12:00 index.html 34 12:05 page1.html 11 12:10 index.html 44 This is one attempt, but no output. select pages_timestamp, (select count( pages_name) from pages t2 where UNIX_TIMESTAMP(t2.pages_timestamp) DIV 300 = UNIX_TIMESTAMP(pages_timestamp) group by pages_name order by count(pages_name) desc limit 1 ) from pages where ... group by UNIX_TIMESTAMP(pages_timestamp ) DIV 300 I'm sure there is a better approach
This assumes page_timestamp is a DATETIME type. Here is a sample with some data I created, it helps to visualize the output. So first off, lets create a function for time rounding, this will declutter our query: drop function if exists rtime; create function rtime (time DATETIME) returns DATETIME BEGIN DECLARE newtime DATETIME; set newtime = from_unixtime(floor(unix_timestamp(time)/300)*300); return newtime; END; Next let's explore our data a little bit. I want to pull all Time, Page, and Count(Page_Name), grouping by interval and page. SELECT Time, Page, Hits from ( select rtime(pages_timestamp) as time , page_name as page , count(page_name) as hits from pages group by page_name, rtime(pages_timestamp) order by rtime(pages_timestamp), hits desc) g ; This orders our aggregated table by time interval then the number of hits. Since our groups are ordered by most hits desc we can pull the first row. In MySQL we can non-aggregate non-group by columns (src. This gives us the first row per group, the one with the most hits. We just SELECT * from the above table grouping only by time: select * from (select time, page, hits from ( select rtime(pages_timestamp) as time , page_name as page , count(page_name) as hits from pages group by page_name, rtime(pages_timestamp) order by rtime(pages_timestamp), hits desc ) g ) h group by time; Disclaimer!: If there is a tie, if two pages both have the most hits, this will only pull one record.