我对SQL非常陌生。我只能做Excel宏。 我有储水箱容积表,其ID,高度和容积如下所示
Id Height Volume 1 0 0 2 1 1000 3 2 1950 4 3 3050 5 4 4020 6 5 5000
我需要一个sql代码来计算实际罐高为3.5时的比例值。
答案应该是(((4020-3050)/(4-3))*(3.5-3))+3050 = 3535
。
答案 0 :(得分:0)
没有给出DBMS,但是此答案适用于MySql,并且基于所谓的Windows函数,希望它也可以在其他DBMS上使用。
内部子查询在同一行上创建一个高度,高度,前一行高度,体积和前一行体积的表。这样就可以选择正确的行,并根据给定的高度对体积进行线性插值
SELECT DISTINCT ((volume - prev_volume)/(height - prev_height)) * (@given_height - prev_height) + prev_volume AS calculated_volume
FROM (SELECT height,
LAG(height, 1) OVER w AS prev_height,
volume,
LAG(volume, 1) OVER w AS prev_volume
FROM volume
WINDOW w AS (ORDER BY height ASC)) AS t
WHERE @given_height BETWEEN prev_height and height
答案 1 :(得分:0)
这是另一种解决方案,它使用标准的ANSI sql,并且不依赖于窗口函数,因此应该适用于大多数RDBMS /版本。
原理是使用子查询查找给定高度附近最接近的记录的ID,然后在外部查询中进行计算。您需要将?
替换为要为其计算体积的高度。
SELECT
(tsup.volume - tinf.volume)
/ (tsup.height - tinf.height)
* (? - tinf.height)
+ tinf.volume
as regression
FROM
(
SELECT t.*
FROM mytable t
WHERE id = (SELECT MIN(id) FROM mytable WHERE height > ?)
) tsup
CROSS JOIN (
SELECT t.*
FROM mytable t
WHERE id = (SELECT MAX(id) FROM mytable WHERE height < ?)
) tinf
SET @search = 3.5;
SELECT
(tsup.volume - tinf.volume)/(tsup.height - tinf.height)*(@search - tinf.height) + tinf.volume regression
FROM
(
SELECT t.*
FROM mytable t
WHERE id = (SELECT MIN(id) FROM mytable WHERE height > @search)
) tsup
CROSS JOIN (
SELECT t.*
FROM mytable t
WHERE id = (SELECT MAX(id) FROM mytable WHERE height < @search)
) tinf;
| regression | | ---------- | | 3535 |
答案 2 :(得分:0)
您想要下一个最小值和最大值。您可以使用:
(select t.*
from t
where t.height <= 3.5
order by t.height desc
fetch first 1 row only
) union all
(select t.*
from t
where t.height >= 3.5
order by t.height asc
fetch first 1 row only
)
使用此信息,您可以进行所需的计算:
select (case when min(height) = max(height)
-- exact match
then min(volume)
else (min(volume +
(max(volume) - min(volume)) / (max(height - min(height)) * (3.5 - min(height)
)
end) as interpolated_volume
from ((select t.*
from t
where t.height <= 3.5
order by t.height desc
fetch first 1 row only
) union all
(select t.*
from t
where t.height >= 3.5
order by t.height asc
fetch first 1 row only
)
) t;
这假定体积随高度增加-在这种情况下,这似乎非常合理。可以针对其他情况调整此代码。
请注意,这使用标准的SQL语法元素。一些数据库的语法略有不同。