У мене виникла проблема з визначенням кількості днів прострочення, де клієнт був менше, ніж на 3 дні пізніше. Я намагаюся побудувати функцію для повернення кількості прострочених днів, де клієнт був менше, ніж на 3 дні пізніше. Я використовую базу даних dvdrental, надану PostgreSQL. Здається, що вона повертає 6 для кожного рядка, ймовірно, кількість першого клієнта, який зустрівся, або, принаймні, так я вважаю. Ось що я намагаюся зробити і в чому мені потрібна допомога:
1 2 3 4 |
Customer_ID | days_past_due 1 | 2 1 | 2 1 | 1 |
1 2 3 4 |
Customer_ID | days_past_due 1 | 3 1 | 3 1 | 3 |
1 |
create or replace function pd_lt3(customer_id varchar(45),days_past_due smallint) returns smallint language plpgsql as $$ declare pd_lt3 smallint; begin select total from( select customer_id,count(*) as total from past_due_detail where days_past_due < 3 group by customer_id ) into pd_lt3; return pd_lt3; end; $$; |
Для отримання більш детальної інформації про проблему, я розглянув наступне:
1 2 3 4 5 6 7 8 9 10 11 12 |
CREATE TABLE past_due_detail( customer_id integer not null, first_name varchar not null, last_name varchar not null, rental_id integer not null, rental_date timestamp not null, return_date timestamp, title varchar not null, days_past_due smallint, primary key (rental_id), foreign key (customer_id) references customer(customer_id) ); |
1 2 3 4 5 6 7 8 9 |
CREATE OR REPLACE FUNCTION public.days_past_due( rental_date timestamp without time zone, return_date timestamp without time zone, rental_duration smallint, last_update timestamp without time zone) RETURNS integer LANGUAGE 'plpgsql' COST 100 VOLATILE PARALLEL UNSAFE AS $BODY$ declare days_past_due int; begin select ((cast(return_date as date)) - (cast(rental_date as date)) - rental_duration) where ((cast(return_date as date)) - (cast(rental_date as date)) - rental_duration) > 0 and return_date is not null into days_past_due; return days_past_due; select ((cast(last_update as date)) - (cast(rental_date as date)) - rental_duration) where ((cast(last_update as date)) - (cast(return_date as date)) - rental_duration) > 0 and return_date is null into days_past_due; return days_past_due; end; $BODY$; |
1 2 3 4 5 6 7 8 9 |
insert into past_due_detail( select rental.customer_id,first_name,last_name,rental_id,rental_date,return_date,title,days_past_due(rental_date,return_date,rental_duration,rental.last_update) from inventory inner join film on film.film_id = inventory.film_id inner join rental on rental.inventory_id = inventory.inventory_id inner join customer on rental.customer_id = customer.customer_id where days_past_due(rental_date,return_date,rental_duration,rental.last_update) > 0 order by rental_date,rental.customer_id ); |