Reputation: 193
I'm new to SQL, and I can't seem to find this answered anywhere else. I'm working on a project that requires me to convert between two different grids, which has been fairly straightforward in Excel. I have 2 tables of these forms (filled in first few rows for reference):
JDAY TL1 TL2 TL3
1.5 148.2 147.3 146.4
2.5 150.2 150.1 150.0
3.5 151.1 150.7 150.3
Layer Elevation
2 150.9
3 149.9
4 148.9
5 147.9
6 146.9
7 145.9
In Table1, the values under TL1, TL2, TL3 are elevations that will correspond to the Elevation column in Table2. I want to output a view like this:
JDAY TL1 TL2 TL3
1.5 5 6 7
2.5 3 3 3
3.5 2 3 3
I need to search for the nearest less than elevation in Table2 for each value in Table1, and ouput the corresponding Layer number. I'm not sure how to do this since the elevations aren't exact matches. This works well using the vlookup() function in Excel. Another thing to note is that this is a small piece of the data...there are actually 15 TL columns and 365 JDAY values.
Upvotes: 1
Views: 1807
Reputation: 117487
Firstly, your table1 should probably be normalised a bit:
create table measurements (
jday date not null,
measure varchar(5) not null,
value decimal(6,2) not null,
primary key (jday, measure)
);
So your dataset would be represented as:
jday measure value
2012-05-01 TL1 148.2
2012-05-01 TL2 147.3
2012-05-01 TL3 146.4
...
(I assume that your JDAY column holds a date?)
Now, for your question, since you're using MySql, you can combine orderby, group by and subselects to get the result you're after. There are other ways to arrive at the same result, but I think this is fairly readable:
select * from (
select m.*
from measurements m
join layers l
where l.elevation <= m.value
order by l.elevation desc ) x
group by jday, measure
order by jday, measure
Upvotes: 0
Reputation: 1883
Given the small number of rows involved the following could work:
SELECT A.JDAY,
(select max(layer) from table2 where elevation<=A.tl1) as tl1,
(select max(layer) from table2 where elevation<=A.tl2) as tl2,
(select max(layer) from table2 where elevation<=A.tl3) as tl3,
...
FROM table1 AS A
Upvotes: 1
Reputation: 360672
It'll be ugly, but something like this might do:
SELECT JDAY, MAX(TL1) AS tl1, MAX(TL2) AS tl2, ...
FROM (
SELECT JDAY, othertable.Layer AS TL1, othertable.Layer AS TL2, etc...
FROM maintable
INNER JOIN othertable AS tl1 ON maintable.TL1 < othertable.TL1
INNER JOIN othertable AS tl2 ON maintable.TL2 < othertable.TL2
etc...
) AS subquery
basically, the inner query gets all joined records where the othertable elevations are LESS than the maintable's. Then the other query selects the MAX() of each field, which should be the values you're looking for.
Upvotes: 2