Reputation: 57
My input data is like this
wavelength reflectance
341.6 1.15
343.1 1.14
344.7 1.13
346.3 1.14
347.9 1.14
349.5 1.12
351.1 1.12
352.6 1.13
354.2 1.13
I am using this formula Query
WITH CTE AS(
SELECT
ROW_NUMBER() OVER(
PARTITION BY CAST(wavelength AS INT)
-CAST(wavelength AS INT)%5
ORDER BY wavelength) AS ROW_ID,
wavelength,
avg( reflectance ) OVER(
PARTITION BY CAST(wavelength AS INT)
-CAST(wavelength AS INT)%5
ORDER BY wavelength
rows BETWEEN 1 FOLLOWING
and UNBOUNDED FOLLOWING) As reflectance
FROM
test
)
select trunc(wavelength/5)*5 AS wavelengthwavelength, reflectance
from CTE
where row_id = 1
In this query it povides the output like this
wavelength reflectance
340 2.6400000000000000
340 2.5200000000000000
345 2.5200000000000000
355 2.5500000000000000
360 2.4250000000000000
365 2.4650000000000000
365 2.5450000000000000
370 2.4733333333333333
380 2.6600000000000000
385 2.7400000000000000
390 2.7700000000000000
390 2.8833333333333333
In this output 340,365,390 is placed as twice, instead of placed as twice it should be placed as once only based on the min value, how should do this...
Upvotes: 0
Views: 167
Reputation: 657942
WITH cte AS(
SELECT row_number() OVER(PARTITION BY wavelength::int - wavelength::int%5
ORDER BY wavelength) AS row_id,
wavelength,
avg(reflectance) OVER(PARTITION BY wavelength::int - wavelength::int%5
ORDER BY wavelength
ROWS BETWEEN 1 FOLLOWING
AND UNBOUNDED FOLLOWING) AS reflectance
FROM test
)
SELECT DISTINCT ON (1)
trunc(wavelength/5)*5 AS wavelength, reflectance
FROM cte
WHERE row_id = 1
ORDER BY 1, 2;
DISTINCT ON
is a Postgres extension to standard SQL DISITNCT
and is particularly useful if you want to add more columns and still pick the row with minimum reflectance
. Otherwise GROUP BY
can to the job as well.
More details in this related answer:
Select first row in each GROUP BY group?
With DISTINCT ON
, you need ORDER BY
in the final SELECT
. However, you will want to add that either way. Per documentation:
Currently, window functions always require presorted data, and so the query output will be ordered according to one or another of the window functions'
PARTITION BY
/ORDER BY
clauses. It is not recommended to rely on this, however. Use an explicit top-levelORDER BY
clause if you want to be sure the results are sorted in a particular way.
Upvotes: 1
Reputation: 57421
select wavelength, MIN(reflectance)
FROM (select trunc(wavelength/5)*5 AS wavelength, reflectance
from CTE
where row_id = 1) src
GROUP BY wavelength
Upvotes: 0
Reputation: 3128
I think that the best way is that you use trunc(wavelength)
exchange of trunc(wavelength/5)*5
but if you don't want to do that you can do something like this:
select trunc(trunc(wavelength * 5) / 5) AS wavelengthwavelength, reflectance
from CTE
where row_id = 1
Upvotes: 0