postgresql how to get min and max value from specific range - sql

I have this table of log finger print attendannce.
and i want to select the table with the result like this.
as you can see, in the mindailylog field, it contains the minumum date of that day, and the maxdailylog field value contains the max value of that day.

You can use window functions:
select t.*,
min(waktuabsen) over (partition by userid, waktuabsen::date),
max(waktuabsen) over (partition by userid, waktuabsen::date),
from t;
This does the minimum per user_id. If you want the overall minimum, just remove userid from the partition by.

Related

How to get the previous non 0 value from a table?

I still have not read a simple solution to this problem.
This is the table that I have:
This is the result that I want:
Basically, if the value for column SeriesStartRowNum is 0, it should retrieve the lastest, previous non 0 value from the table.
Anyone that knows how to easily do this?
Thanks in advance!
This is untested, due to images of data, but this looks like a gaps and island problem. One method, therefore, would be to use a windowed COUNT to count the number of non-zero values so far in the column SeriesStartRowNum to create "groups", and then in get the MAX value for SeriesStartRowNum in that group:
WITH Groups AS(
SELECT RowNumber,
CustomerID,
Value,
StartDate,
EndDate,
SeriesStartRowNum,
COUNT(NULLIF(SeriesStartRowNum,0)) OVER (/*PARTTION BY ???*/ ORDER BY RowNumber) AS Grp
FROM dbo.YourTable)
SELECT RowNumber,
CustomerID,
Value,
StartDate,
EndDate,
MAX(SeriesStartRowNum) OVER (PARTITION BY Grp)
FROM Groups;
If your actual data is like the sample data that you posted, with the 1st row of each combination of CustometID and Value having a non-0 value and all the rest are 0s, then all you need is MAX() window function:
SELECT RowNumber, CustometID, Value, StartDate, EndDate,
MAX(SeriesStartRowNum) OVER (PARTITION BY CustometID, Value) SeriesStartRowNum
FROM tablename

Is there a way to calculate percentile using percentile_cont() function over a rolling window in Big Query?

I have a dataset with the following columns
city
user
week
month
earnings
Ideally I want to calculate a 50th % from percentile_cont(earnings,0.5) over (partition by city order by month range between 1 preceding and current row). But Big query doesn't support window framing in percentile_cont. Can anyone please help me if there is a work around this problem.
If I understand correctly, you can aggregate into an array and then unnest:
select t.*,
(select percentile_cont(earning) over ()
from unnest(ar_earnings) earning
limit 1
) as median_2months
from (select t.*,
array_agg(earnings) over (partition by city
order by month
range between 1 preceding and current month
) as ar_earnings
from t
) t;
You don't provide sample data, but this version assumes that month is an incrementing integer that represents the month. You may need to adjust the range depending on the type.

Obtain latest record for a given second Postgres

I have data with millisecond precision timestamp. I want to only filter for the most recent timestamp within a given second. Ie. records (2020-07-13 5:05.38.009, event1), (2020-07-13 5:05.38.012, event2) should only retrieve the latter.
I've tried the following:
SELECT
timestamp as time, event as value, event_type as metric
FROM
table
GROUP BY
date_trunc('second', time)
But then I'm asked to group by event as well and I see all the data (as if no group by was provided)
In Postgres, you can use distinct on:
select distinct on (date_trunc('second', time)) t.*
from t
order by time desc;

Group records for hourly count

My goal is to build an hourly count for records that have a start date/time and an end date/time. The actual records are never more than 24 hours from start to finish but many times are less. It works if I bounce every record against my "clock" which has 24 slots for every date up to "today". But it can take forever to run as there can be 2000 records in a day.
This is the detail I get:
The date/times in green are what I want as the start date/time for a group. The blue date/times are what I want as the end date time for the group.
Like this:
I have tried partitioning but because, in the second pic, the 4th row has the same values as the 2nd row, it groups them together even though there is a time span between them - the third row.
This is a gaps-and-islands problem. The start and end dates match on adjacent rows, so a difference of row numbers seems sufficient:
select id, min(startdatetime), max(enddatetime),
d_id, class, location
from (select t.*,
row_number() over (partition by id order by startdatetime) as seqnum,
row_number() over (partition by id, d_id, class, location) as seqnum_2
from t
) t
group by id, d_id, class, location, (seqnum - seqnum_2);
order by id, min(startdatetime);

SELECT columns OVER (PARTITION BY column)

Suppose I want to retrieve the swimmer and their time at the 75th Percentile for each day.
This is what I was trying to do:
SELECT tableA.DATE, tableA.SWIMMER, tableA.TIME
OVER (PARTITION BY tableA.DATE)
FROM tableA
WHERE RANK = CEIL(0.75 * NUM_OF_SWIMMERS);
But this errors at the OVER statement.
What's the best way to get the data I need?
Thanks!
Your error is that the OVER clause of a windowing function requires an ORDER BY clause.
But assuming that num_swimmers , why not just return
select
date,
swimmer,
time
from tablea
where
RANK = CEIL(0.75 * NUM_OF_SWIMMERS)
?
The WHERE clause will ensure the only rows returned are the 75th percentile for a given day