Reputation: 971
Hi I need help on designing database table for the following rules :
There is a need of a storage of data for the weather of each day.It needs to store either 1 or 2 values of weather as defined by the system.
The following parameter needs to be applied while designing the table.
If the weather is above 100 Fahrenheit we need to store the value and a column indicating the weather is above threshold
If the weather is below 20 Fahrenheit we need to store the value and a column indicating the weather is below threshold
If the weather is above 40 Fahrenheit and below 80 Fahrenheit we need to store the value and a column indicating the weather is in-range
If the weather is below 40 Fahrenheit and above 80 Fahrenheit we need to store the value and a column indicating the weather is not in range
Thanks in advance.
Upvotes: 0
Views: 226
Reputation: 5730
If you are using MySQL 5.7 you could use GENERATED COLUMNS:
create table wheather (
temp int,
hot int generated always as (if(temp>30,1,0)) virtual,
cold int generated always as (if(temp<20,1,0)) virtual
);
insert into wheather (temp) values (10), (20), (30), (40);
select * from wheather;
Gives:
temp hot cold
-------------------
10 0 1
20 0 0
30 0 0
40 1 0
If using earlier versions of MySQL, like 5.5, use a view that does the same.
Update: From the comments I learned that the thresholds vary for different locations. Given that, I suggest a second table that holds the thresholds for each location and then join the two tables:
create table wheather (
location char(20),
temp int
);
insert into wheather (location, temp) values
('Florida', 10), ('Florida', 20), ('Florida', 30), ('Florida', 40),
('Alaska', 10), ('Alaska', 20), ('Alaska', 30), ('Alaska', 40);
create table thresholds (
location char(20),
low int,
high int,
inrange_lower int,
inrange_upper int,
outrange_lower int,
outrange_upper int
);
insert into thresholds values
('Florida', 30, 60, 35, 45, 20, 50),
('Alaska', 10, 30, 15, 25, 5, 40);
select w.location,
w.temp,
if(w.temp < t.low,'yes','no') as cold,
if(w.temp > t.high,'yes','no') as hot,
if(w.temp between t.inrange_lower and t.inrange_upper,'yes','no') as in_range,
if(w.temp < t.outrange_lower or w.temp > t.outrange_upper,'yes','no') as out_of_range
from wheather w left join thresholds t on w.location=t.location;
Gives:
+----------+------+------+-----+----------+--------------+
| location | temp | cold | hot | in_range | out_of_range |
+----------+------+------+-----+----------+--------------+
| Florida | 10 | yes | no | no | yes |
| Florida | 20 | yes | no | no | no |
| Florida | 30 | no | no | no | no |
| Florida | 40 | no | no | yes | no |
| Alaska | 10 | no | no | no | no |
| Alaska | 20 | no | no | yes | no |
| Alaska | 30 | no | no | no | no |
| Alaska | 40 | no | yes | no | no |
+----------+------+------+-----+----------+--------------+
8 rows in set (0.00 sec)
The code works, but is simplified, i.e. it lacks PKs, INDEXEs, FK constraints, and a DATE column. And I may have gotten the actual values and/or comparisons wrong, but it may point you to a direction.
Of course you can create a view for the SELECT statement. If you really want to store the values, then I suggest four extra columns in the WHEATHER table (cold/hot/in_range/out_of_range) and populate them with an INSERT trigger with the values from the THRESHOLD table. This way you can change the thresholds (in THRESHOLDS) later without changing the values in WHEATHER. For example, if you'd created your database 50 years ago, then 50 °F would be considered hot whereas meanwhile 55 °F is hot (due to climate change). It depends on your use case. The view gives "life updates", the trigger gives "historical values".
Upvotes: 2