С Postgres рассчитайте для набора входной даты доступность на основе трех таблиц и условных значений - PullRequest
0 голосов
/ 21 октября 2018

Допустим, у вас есть три таблицы:

[default_limit]
id | location | limit

[daily_limit]
date | location | id | limit

[reserved]
date | location | id | quantity

, и у вас есть такие данные, как

{
  date: '10/21/18',
  location: 1,
  request: [
    {
       id: 1,
       quantity: 3
    },
    {
       id: 2,
       quantity: 1
    }
  ]
}

Какой самый эффективный способ выполнить следующие вычисления для каждого идентификатора запроса иколичество и вернуть единственное логическое значение, представляющее, если все верно:

limit = false 
if (daily_limit for date/location/id) 
  limit = daily_limit
else if (default_limit for date/location/id)
  limit = default_limit

if (limit) 
  return quantity + reserved.quantity <= limit
else 
  return true

Исходя из некоторых похожих вопросов, я пытался объединить таблицы по идентификатору и местоположению, а затем COALESCE (daily_limit.limit, default_limit.limit) но я не знаю, как включить в нее дату или справиться с ситуацией, когда ее не существует, а комбинация дата / местоположение / идентификатор не ограничена.

В настоящее время я работаю над этим в приложении.код, но я изложил схему таким образом, зная, что должен быть хитрый способ сделать это непосредственно в SQL.

Любые толчки в правильном направлении будут с благодарностью, спасибо!

1 Ответ

0 голосов
/ 21 октября 2018

Я думаю, вы можете начать с этого, быстро и грязно

create table default_limit (id int,location int, "limit" int );
create table daily_limit (id int,location int, "limit" int, dt date );
create table reserved (id int,location int, quantity int, dt date );

insert into default_limit(id,location,"limit") values (1,1,5);
insert into default_limit(id,location,"limit") values (2,1,5);

insert into daily_limit(id,location,"limit",dt) values (1,1,3,'10/21/18'::DATE);

insert into reserved(id,location,quantity,dt) values (1,1,1,'10/21/18'::DATE);

create or replace function q(p_id int,p_location int,p_quantity int, p_dt date)
RETURNS boolean
as $$
select 
  coalesce(
  (p_quantity + coalesce(l3.quantity,0))
  <=
  coalesce(l2."limit",l1."limit",2147483647)
  ,true)
  from
  (select * from default_limit where id = p_id
                                 and location = p_location
                                 limit 1) l1
   full join 
   (select * from daily_limit where id = p_id
                                 and location = p_location
                                 and dt = p_dt
                                 limit 1) l2
   on true                              
   full join
   (select * from reserved where id = p_id
                                 and location = p_location
                                 and dt = p_dt
                                 limit 1) l3
   on true                              
   full join (select 1 as p) ph on true
$$ language sql;

select q(1,1,1,'10/21/18'); -- true
select q(1,1,2,'10/21/18'); -- true
select q(1,1,3,'10/21/18'); -- false


select q(3,4,42,'10/22/18'); -- true
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...