Access the previous row in select - sql

I have a scenario as below
--source data
departuredttm flight_source flight_destination available_seats
13-07-2016 04:00:00 A B 200
13-07-2016 08:00:00 A B 320
13-07-2016 08:20:00 A B 20
I have a lookup table which tell how many total passengers are there for this source and destinatin whose flights are delayed and needs to adjusted in available seats in source data.lookup table is like this.
--lookup table for passenger_from_delayed_flights
flight_source flight_destination passengers
A B 500
now I have to adjust these 500 passengers in available seats as in source data
---output
DepartureDttm flight_source flight_destination AVAILABLE_SEATS PASSENGERS_TO_ADJUST PASSENGER_LEFT
13-07-2016 04:00:00 A B 200 500 300
13-07-2016 08:00:00 A B 320 300 20
13-07-2016 08:20:00 A B 20 20 0
initially passenger to adjust is 500 where we have 200 seats , next 320 seats are available and we have to adjust 300 (500-200) passengers.
Please help
Thanks

Your expected result is probably wrong, the 2nd flight already has enough seats, so PASSENGER_LEFT should be -20 (or 0).
This is a calculation based on a running total:
passengers - SUM(available_seats)
OVER (ORDER BY departuredttm
ROWS UNBOUNDED PRECEDING) AS PASSENGER_LEFT
available_seats + PASSENGER_LEFT AS PASSENGERS_TO_ADJUST

Related

Cumulative over table rows with condition Oracle PL/SQL

I have two tables:
Employees:
employee_id field max_amount
3 a 3000
4 a 3000
1 a 1600
2 a 500
4 b 4000
2 b 4000
3 b 1700
ordered by employee, field, amount desc.
Amounts (pol, premia,field):
pol premia field **assign_to_employee**
11 900 a 3
44 1000 a 3
55 1400 a 4
77 500 a 3
88 1300 a 1
22 800 b 4
33 3900 b 2
66 1300 b 4
Assign Stats Table:
employee_id field max_amount true_amount remain
3 a 3000 2400 600
4 a 3000 1400 1600
1 a 1600 1300 300
2 a 500 0 500
4 b 4000 2100 1900
2 b 4000 3900 100
3 b 1700 0 1700
The output : assign_to_employee field (merged to amounts table).
Algoritem wise : The method is to assign pol's to employees until the premia needs to be added to the cumulative_sum is bigger then the max amount per employee listed in the employees table. You always start with the employess with most max amount until you cannot add any other pols to the employee.
I start with the employees with the grater max_amount per field.
I keep doing this until no pols remains to be assign.
Can you help me solve this?
Thank you.

Getting price difference between two dates

There is a table where once a day/hour lines are added that contain the product ID, price, name and time at which the line was added.
CREATE TABLE products
(
id integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
product_id integer NOT NULL,
title text NOT NULL,
price double precision NOT NULL,
checked_at timestamp with time zone DEFAULT now()
);
The data in the products table looks like this:
id
product_id
title
price
checked_at
1
1000
Watermelon
50
2022-07-19 10:00:00
2
2000
Apple
30
2022-07-19 10:00:00
3
3000
Pear
20
2022-07-19 10:00:00
4
1000
Watermelon
100
2022-07-20 10:00:00
5
2000
Apple
50
2022-07-20 10:00:00
6
3000
Pear
35
2022-07-20 10:00:00
7
1000
Watermelon
150
2022-07-21 10:00:00
8
2000
Apple
50
2022-07-21 10:00:00
9
3000
Pear
60
2022-07-21 10:00:00
I need to pass a date range (for example, from 2022-07-19 to 2022-07-21) and get the difference in prices of all unique products, that is, the answer should be like this:
product_id
title
price_difference
1000
Watermelon
100
2000
Apple
20
3000
Pear
40
I only figured out the very beginning, where I need to get the ID of all unique products in the table using DISTINCT. Next, I need to find the rows that are closest to the date range. And finally find the difference in the price of each product.
You could use an aggregation approach here:
SELECT product_id, title,
MAX(price) FILTER (WHERE checked_at::date = '2022-07-21') -
MAX(price) FILTER (WHERE checked_at::date = '2022-07-19') AS price_difference
FROM products
GROUP BY product_id, title
ORDER BY product_id;

Quicksight Calculated field: sum of average?

The dataset I have is currently like so:
country
itemid
device
num_purchases
total_views_per_country_and_day
day
USA
ABC
iPhone11
2
900
2022-06-15
USA
ABC
iPhoneX
5
900
2022-06-15
USA
DEF
iPhoneX
8
900
2022-06-15
UK
ABC
iPhone11
10
350
2022-06-15
UK
DEF
iPhone11
20
350
2022-06-15
total_views_per_country_and_day is already pre-calculated to be the sum grouped by country and day. That is why for each country-day pair, the number is the same.
I have a Quicksight analysis with a filter for day.
The first thing I want is to have a table on my dashboard that shows the number of total views for each country.
However, if I were to do it with the dataset just like that, the table would sum everything:
country
total_views
USA
900+900+900=2700
UK
350+350=700
So what I did was, create a calculated field which is the average of total_views. Which worked---but only if my day filter on dashboard was for ONE day.
When filtered for day = 2022-06-15: correct
country
avg(total_views)
USA
2700/3=900
UK
700/2=350
But let's say we have data from 2022-06-16 as well, the averaging method doesn't work, because it will average based on the entire dataset. So, example dataset with two days:
country
itemid
device
num_purchases
total_views_per_country_and_day
day
USA
ABC
iPhone11
2
900
2022-06-15
USA
ABC
iPhoneX
5
900
2022-06-15
USA
DEF
iPhoneX
8
900
2022-06-15
UK
ABC
iPhone11
10
350
2022-06-15
UK
DEF
iPhone11
20
350
2022-06-15
USA
ABC
iPhone11
2
1000
2022-06-16
USA
ABC
iPhoneX
5
1000
2022-06-16
UK
ABC
iPhone11
10
500
2022-06-16
UK
DEF
iPhone11
20
500
2022-06-16
Desired Table Visualization:
country
total_views
USA
900 + 1000 = 1900
UK
350 + 500 = 850
USA calculation: (900 * 3)/3 + (1000 * 2) /2 = 900 + 1000
UK calculation: (350 * 2) /2 + (500 * 2) /2 = 350 + 500
Basically---a sum of averages.
However, instead it is calculated like:
country
avg(total_views)
USA
[(900 * 3) + (1000*2)] / 5 = 940
UK
[(350 * 2) + (500 * 2)] / 4 = 425
I want to be able to use this calculation later on as well to calculate num_purchases / total_views. So ideally I would want it to be a calculated field. Is there a formula that can do this?
I also tried, instead of calculated field, just aggregating total_views by average instead of sum in the analysis -- exact same issue, but I could actually keep a running total if I include day in the table visualization. E.G.
country
day
running total of avg(total_views)
USA
2022-06-15
900
USA
2022-06-16
900+1000=1900
UK
2022-06-15
350
UK
2022-06-16
350+500=850
So you can see that the total (2nd and 4th row) is my desired value. However this is not exactly what I want.. I don't want to have to add the day into the table to get it right.
I've tried avgOver with day as a partition, that also requires you to have day in the table visualization.
sum({total_views_per_country_and_day}) / distinct_count( {day})
Basically your average is calculated as sum of metric divided by number of unique days. The above should help.

Moving Median PostgreSQL with Partition

I'm looking to create a prior rolling 4 quarter Median. Some entries have less than 4 quarters, some have more. I want this by Employee. Needs to account for different tenure for different employees.
Result for 2021-1 should represent the prior 4 quarters median (and not account for current quarter).
I was able to figure out a rolling average with partitioning but not sure how to tackle a rolling median.
Thanks!
Employee ID
Quarter
Sales
EXPECTED RESULT
A
2020-1
1000
NULL
A
2020-2
2000
1000
A
2020-3
3000
1500
A
2020-4
4000
2000
A
2021-1
5000
2500
A
2021-2
4000
3500
B
2020-3
8000
NULL
B
2020-4
7000
8000
B
2021-1
6000
7500
B
2021-2
5000
7000
B
2021-3
1000
6500
C
2021-1
5000
NULL
C
2021-2
0
5000
C
2021-3
4000
2500

Get day by day repeated data with postgres

I have transactions table with columns id, user_id, currency, amount and created_at;
I want to write function to check in last x days transaction with exist amount repeated or not.
For example user makes transaction per 200$ in 5 days, and 6th days wants to make transaction in 250$. Function have to check did user make transaction in last 5 days per 250$ or not. In this example function have to return false. Because user breaks rule.
If user want to make transaction with 200$ function have to return true;
I have tried with
select count(*) from "transactions" where "created_at" >= NOW()- INTERVAL '5 DAY' and "amount"=250 and "currency" = "USD"
but this gives me incorrect answer, becouse if user makes a transaction twise a day, this function calculates 5 items in 4 day. If n transactions in a day I have to calculate it 1 transaction.
So:
id user_id currency amount created_at
1 1 USD 200 2021-05-15 16:00:01
2 1 USD 200 2021-05-16 18:05:28
3 1 USD 200 2021-05-17 11:33:55
4 1 USD 200 2021-05-18 12:00:01
5 1 USD 200 2021-05-18 13:15:01
6 2 USD 250 2021-05-15 16:00:01
7 2 USD 250 2021-05-16 18:05:28
8 2 USD 250 2021-05-17 11:33:55
9 2 USD 250 2021-05-18 12:00:01
10 2 USD 250 2021-05-19 13:15:01
with this data, query have to return 4 items for user with id 1 and amount 200. Have to return 5 items for user with id 2 and amount 250
I think you just want count(distinct). You seem to want different values for each user, so that suggests group by as well:
select user_id, count(distinct created_at::date) as num_days
from "transactions"
where created_at >= NOW()- INTERVAL '5 DAY' and
amount = 250 and
currency = 'USD'
group by user_id;