database design for updating data weekly - mysql

I find it very difficult to explain what I want to ask, So I created a hypothetical question (taking ex of temp), Maybe my question is still not very clear, But pls take a look. let me know if you need any clarification
I want to compare the temp of last Sunday and temp of temp 3 weeks ago (Sunday),
So it should show something like this. There would be two dates in select option so I want to analyze temp on Sunday before last Sunday,
<select>
<option> Last Sunday (2017-12-03) </option>
<option> Previous Sunday (2017-11-26) </option>
</select>
<h1> Temp on 2017-12-03 </h1>
<p> 24 C </p>
<h1> temp 3 weeks ago (2017-11-12)</h1>
<p> 24.4 C</p>
<h1> Change in temp </h1>
<p> .4 </p>
Assume I can get the temp only current Sunday, So I need to update this database on weekly basis (on every sunday)
city_id sunday_temp temp_pre_week1 temp_pre_week2 temp_pre_week3 last_sunday_date
1 24.0 24.3 35.2 24.4 2017-12-03
1 24.3 35.2 24.4 28.0 2017-11-26
2 3.0 4.0 2.0 6.0 2017-12-03
2 4.0 2.0 6.0 7.0 2017-11-26
.
.
around 2000 rows
Another option that i thought would be saving the data for 4 weeks, So when user select the Sunday before last Sunday I would be able to use 4th-week column,
Something like this
city_id sunday_temp temp_pre_week1 temp_pre_week2 temp_pre_week3 temp_pre_week4 last_sunday_date
1 24.0 24.3 35.2 24.4 28.0 2017-12-03
2 3.0 4.0 2.0 6.0 7.0 2017-12-03
.
.
I only want to analyze two Sundays not more than that, So i think adding one more column would be more efficient,
Thanks :)

Don't store all the data for a query in each row. Let the database do the work for you. Your database structure should just include city_id, date,temp. If you only have Sundays included, that's OK. You can then use something like
SELECT `temp`,`date` FROM `citydata` WHERE (`city_id` = 1) and (`date` <= '2017-12-03') ORDER BY `date` DESC LIMIT 4
which will retrieve the last 4 records available for city 1 that are on or before 2017-12-03. If you have data for every Sunday, that will get you the specific date ("last Sunday") plus the 3 previous weeks. If you decide you want more - just change the LIMIT to 5 or 6 or whatever you want. If you later decide to add different days of the week you won't have to change the database structure (though you will need to adjust your queries a bit). Most importantly, you won't need to look to previous records when you are collecting new data - you just add the new records and get the previous weeks of data when you actually need them.

Related

Availability by day and week

I'm trying to come up with a database structure to account for products that are available on certain days of week and on certain weeks ( odd / even )
An example:
- product1 is available for selling Mondays in odd weeks
- product2 is available everyday on even weeks
- product3 is available on weekends
I thought of isolating the availability in a second table with the product as fk and each condition on a separate row like so:
fk_prod1 weekday 1
fk_prod1 weekparity 1
fk_prod2 onweekday 1
fk_prod1 weekparity 0
In this form I don't know how I would get the products that are available for today, for the rest of the week and next week.
Any suggestions are welcome :)
Queries are also much appreciated!
This may help out :) Might needed adjusted depending on your circumstances with the program but heres an idea:
Table 1: Products
This could hold ProductID, ProductName
So a row could look like this: 1, product1
Table 2: ProductDayMatrix (ProductDayID,ProductDay)
1,Monday
2,Tuesday
3,Wednesday
4,Thursday
5,Friday
6,Saturday
7,Sunday
Table 3: ProductWeekMatrix (ProductWeekID, ProductWeek)
1 = odd weeks
2 = even weeks
or like
1, Week1
2, Week2
3, Week3
4, Week4
Finally then Table 4:
Product Matrix: (ProductID,ProductDayID,ProductWeekID)
This could hold your products and their corresponding data. So you would insert data into this table with your information and it would look like this.
(1,4,2) = Product 1, On a Thursday, on the even weeks.
Or if things need multiple conditions have 2 different tables that would hold the day information.
Like: ProductAvailablityMatrixDay & ProductAvailabilityMatrixWeek
Then those could hold mulitple values for each so if product 1 was on monday and thursday you could insert: (1,1) & (1,4). Then reading from that table would tell you that product 1 was on day 1 and 4. Same goes with the weeks.
Would it be worth considering an approach similar to the way cron jobs are structured?
Your day of the week will always be 1-7
Your week of the month will always be 1-6
So using LIKE would give 0 possible conflicts where 1 could be matched to 10 for example as you won't ever have 2 digits.
So if your product1 it could be:
day = 1
week = 1,3,5
For product2 it would be:
day = 1,2,3,4,5,6,7
week=2,4,6
For product3 it would be:
day=6,7
week=1,2,3,4,5,6 (September this year spans 6 different weeks)
The your queries would be something like:
Today:
"SELECT * FROM availability WHERE day LIKE '%".date("N")."%' AND week LIKE %".(date("W")-date("W",strtotime("first day of the month")))."%'";
// this is using some PHP to get the week of the days of the week and week of the month.
Tomorrow:
"SELECT * FROM availability WHERE day LIKE '%".date("N",strtotime("tomorrow")."%' AND week LIKE %".(date("W",strtotime("tomorrow"))-date("W",strtotime("first day of the month")))."%'";
// this again is using some PHP to get the week of the days of the week and week of the month - you can achieve the same with just MYSQL but I'm more familiar with PHP to give you an idea.
I'm not saying its perfect but unless your going to do more with these rows I don't think the use of foreign keys is going to help you? Hope that helps?

SSRS bar chart with multiple categories

I have built some quite ssrs charts, but is it possible to create below bar chart n SSRS.
![click on the link below to show the bar chart][1]
but when am creating this in ssrs , am getting report as below.
I am getting the report in ssrs as below, but not like the above one:
![][2]
If you want to include the heading as they are in your first image, you will need to be clever with your dataset.
Personally I would probably take the approach of including dummy chart values to get your Category heading without a corresponding bar in the chart, such as:
Group Order Category Value
31 to 60 Days 1 31 to 60 Days 0
31 to 60 Days 2 Today 14
31 to 60 Days 3 1 Month Ago 12
31 to 60 Days 4 2 Month Ago 44
Up to 30 Days 1 Up to 30 Days 0
Up to 30 Days 2 Today 11
Up to 30 Days 3 1 Month Ago 8
Up to 30 Days 4 2 Month Ago 21
From which you can:
Group your Categories using the Group value
Display each Category in its correct order by sorting on the Order column
Actually display your chart values using the Value column, which will show nothing for your group headings
How you get your data into that format will depend on your data source, but should be fairly trivial if you are using a SQL source.

MySQL joining the previous occurrence of a record

I have the query that lists that dates that a store was open and closed. What I want is the previous open date so for example for 2014-12-27 it would be 2014-12-26. The store wasn't open on New Years so for 2015-01-02 it would be 2014-12-31.
Every time I sit down to write the query I get nowhere, I have tried subselects, case statements, joining subqueries, subqueries in the where clause and I still can't figure this one out. Any help on this would be much appreciated?
EDIT
Clarifying that the column date_nk is an integer, and add the column "previous_date" to show the desired output.
date_nk weekday opened previous_open_date
1. 20141226 Friday 1 20141225
2. 20141227 Saturday 0 20141226
3. 20141228 Sunday 0 20141226
4. 20141229 Monday 1 20141226
5. 20141230 Tuesday 1 20141229
6. 20141231 Wednesday 1 20141230
7. 20150101 Thursday 0 20141231
8. 20150102 Friday 1 20141231
9. 20150103 Saturday 0 20150102
10. 20150104 Sunday 0 20150102
Please check the below.
Example in SQL Fiddle
SELECT
date_nk,
weekday,
opened,
(select max(date_nk) from OpenTable PO
where PO.date_nk < CU.date_nk and
PO.Opened = 1) PrevDate
from OpenTable CU
order by date_nk;
It doesn't look difficult if I understod you.
SELECT * FROM table WHERE opened = '1' AND date_nk < 'yourdate' LIMIT 1;
I don't knwo the type of your date_nk field, you should think about use date types but I think that should work.

Access Report Subgroup summing

In MS Access 2010, assume a query contains the following results:
Date Activity Hours
1.9. Reading 1
1.9. Writing 2
2.9. Reading 1
3.9. Talking 1
4.9. Reading 3
1.10. Talking 2
1.10. Writing 1
2.10. Reading 2
3.10. Talking 2
4.10. Reading 1
the Report should show the sum of hours spent each month grouped by activity, something like
Month Activity Hours
September Reading 5
Writing 2
Talking 1
October Reading 3
Writing 1
Talking 4
using the wizard I mange to get a report which looks like
Month Activity Hours
September Reading 1
Reading 1
Reading 3
Writing 2
Talking 1
October Reading 2
Reading 1
Writing 1
Talking 2
Talking 2
which is nearly what I'd like to have but.. ?
I tried =sum(Hours), but then all Hours fields simply contain the total sum of all hours, and I still get several lines for the same activity.
Actually the report is more complicated. In a form prior to the report, the user can enter a date range (e.g. September 1 - October 30). The report should sum over the whole time range and not break up to months, that is:
Date range Activity Hours
9/1 - 10/30 Reading 8
Writing 3
Talking 5
Create a query with a SQL like this:
SELECT MonthName(Month([Date])), Activity, SUM(Hours)
FROM yourTable
WHERE [Date] >= xxx AND [Date] <= yyy
GROUP BY MonthName(Month([Date])), Activity
The key element is the GROUP BY clause, it sums the Hours per Month + Activity.
Then base your report on that query.
BTW, it is not a good idea to call a column "Date", it's a reserved word in Access.

Extracting datapoint from mySQL

I have a table within MySQL which is being used to store user session information across a fleet of instances. The structure of the table is pretty simple, with 6 fields.
Item: 37824
Timestamp: 2014-10-30 23:01:41
Active: 14
Idle: 2
Total: 16
Server:
The metrics are collected every 5 minutes.
I have a query which pulls the SUM of one of the metrics for the past 5 minutes.
select SUM(metric_activeSessions) from metrics_tbl WHERE metric_timeStamp > NOW() - INTERVAL 5 MINUTE
I want to build a chart from these metrics, using one of the many great libraries available, but yet to be determined.
I would like the chart to show the SUM of a given metric every over a period of 60 minutes, at 5 minute intervals.
- 09:00 : 12
- 09:05 : 15
- 09:10 : 18
- 09:15 : 21
- 09:20 : 28
I have no idea how to write an SQL query to collect information in that way and was hoping someone out there may be able to help me out.
Thank you in advance for any ideas,
Cheers,
Mitch
Assuming metric_timeStamp is formatted as a mysql timestamp, try something like this..
SELECT SUM(metric_activeSessions), MAX(metric_timeStamp) as max_time, MIN(metric_timeStamp) as min_time,
FROM metrics_tbl
WHERE metric_timeStamp > NOW() - INTERVAL 60 MINUTE
GROUP BY unix_timestamp(metric_timeStamp) div 300
Use that as a starting point. I'm eating ice cream right now so I can't run this myself, but that's the general idea.
Edit: fixed syntax issue
Edit 2: I was grouping by 10 minutes. Changed it to 5 minutes
Edit 3: If your rows contain a running total, then change
SUM(metric_activeSessions)
to
MAX(metric_activeSessions)
in the query above.