我想知道从一行日期进行日期比较时是否可以同时运行IN条件和>条件(仅在IN中找不到)?
例如,如果不存在2018-01-01,它将拉出日期2018-01-02的下一个可用行,并且应该对我提供的随机日期数组执行此操作。 (请勿更改,因为这会输入我不感兴趣的日期。)
示例:
create table trade (
id serial primary key,
year int,
month int,
"data" json
);
insert into trade ("year", "month", "data") VALUES (
2018, 1, '{"2": {"low": 19, "high": 21, "open": 20, "close": 20, "volume": 1000}, "3": {"low": 19, "high": 21, "open": 20, "close": 20, "volume": 1000}}'::json
);
insert into trade ("year", "month", "data") VALUES (
2018, 2, '{"1": {"low": 19, "high": 21, "open": 20, "close": 20, "volume": 1000}, "2": {"low": 19, "high": 21, "open": 20, "close": 20, "volume": 1000}}'::json
SELECT
t.prices,
make_date("year", "month", t.day::int) as date
FROM
trade
JOIN json_each(trade.data) t(day, prices) ON TRUE
WHERE
make_date("year", "month", t.day::int) IN ('2018-01-1', '2018-01-03')
);
希望它返回1950-01-03、2018-01-03和2018-01-02的价格(因为不存在2018-01-01)
我正在开发一个函数,当我提供感兴趣的日期时,它将以1/1的比例显示结果,如果不存在,它将返回下一个可用日期。
答案 0 :(得分:1)
您可以使用generate_series检查给定范围内的所有日期。
SELECT
t.prices,
make_date("year", "month", t.day::int) as date
FROM
trade
JOIN json_each(trade.data) t(day, prices) ON TRUE
WHERE
("year"|| lpad( "month"::text,2,'0') || lpad(t.day,2,'0') )::DATE -- a simulation of
--your make_date function.
IN ( select
generate_series(DATE '2018-01-1',
DATE '2018-01-03',INTERVAL '1 DAY') ::DATE
);
修改
假设我想在1950年1月1日,2001年1月1日和2002年1月4日约会, 等等
您可以在UNION ALL
..
IN ( select
generate_series(DATE '2018-01-1',
DATE '2018-01-03',INTERVAL '1 DAY') ::DATE
UNION ALL
select
generate_series(DATE '1950-01-01',
DATE '1950-01-03',INTERVAL '1 DAY') ::DATE
UNION ALL
select
generate_series(DATE '2002-01-01',
DATE '2002-01-04',INTERVAL '1 DAY') ::DATE
)
..
..
答案 1 :(得分:1)
假设差距可能大于一天,那么以下功能似乎是最简单有效的解决方案:
create or replace function trade_on_dates(variadic date[])
returns table (prices json, date date)
language plpgsql stable as $$
declare
d date;
begin
foreach d in array $1 loop
return query select
t.prices,
make_date("year", "month", t.day::int) as date
from trade
join json_each(trade.data) t(day, prices) on true
where make_date("year", "month", t.day::int) >= d
order by 2
limit 1;
end loop;
end $$;
select *
from trade_on_dates('2018-01-01', '2018-01-03');
prices | date
------------------------------------------------------------------+------------
{"low": 19, "high": 21, "open": 20, "close": 20, "volume": 1000} | 2018-01-02
{"low": 19, "high": 21, "open": 20, "close": 20, "volume": 1000} | 2018-01-03
(2 rows)