我有一个应用程序(将PostgreSQL 9.6迁移到10上),我想在其中检索表中的结果,并且与此时间匹配该表中存储的开放时间。
让我们用一个虚拟的例子来解释: 我有一张商店表:
store_name | opening_hours
-----------------+-----------------------------
storeA | ((wday between 1 and 5) and (hour between 10 and 20))
storeB | ((wday between 2 and 5) and (hour between 9 and 18)) OR (wday in (6,7) and (hour between 9 and 12))
我想查询该表并从查询时开始抓取已打开的商店(无时区困扰)。 (谁在乎谁:在我国,一周的第一天是星期一,但在此示例中我们不在乎):
您能帮我使这件小事起作用吗?我认为我只是缺少正确的编写方法。
编辑:“开放时间”仅是记录我要解决此问题的方式的事情。绝不会在该数据库中添加一些新表。 此处搜索的唯一答案是一种评估表中存储的表达式的方法。
答案 0 :(得分:0)
由于您愿意接受建议,因此建议您查看该问题的可接受答案:Best way to store working hours and query it efficiently
您当前的表结构将很难管理。如果您更改了表的结构以匹配上面接受的答案,那么正是您所需要的,这将使查询非常简单。
编辑:为完整起见,链接中建议的表结构为:
要存储正常运行时间,您需要存储一些包含以下内容的记录:
答案 1 :(得分:0)
我对下面的回答并不完全满意,但是它可以按我想要的方式工作,而不是mysql低技术含量的方式。 我在下面的工作基于How to execute a string result of a stored procedure in postgres。
如果有帮助,这里是:
-- push message to debug, to 'RAISE' usefull things
SET client_min_messages TO DEBUG;
\set VERBOSITY terse
-- must return a SETOF to evaluate my test (see RETURN QUERY EXECUTE below)
-- so here is a dirty simple [temporary] table.
CREATE TEMP TABLE stupid_bool_table (opened BOOLEAN);
INSERT INTO stupid_bool_table VALUES (true),(false);
CREATE OR REPLACE FUNCTION grab_worker_test_opening_hour(shopNametext)
RETURNS SETOF stupid_bool_table AS
$BODY$
DECLARE
-- $Id: batch_workers.psql,v 1.15 2018/07/25 08:08:49 calyopea Exp $
openhour text;
BEGIN
--TODO: materialized view refreshed each hours or halfs OR clever query
SELECT INTO openhour description
FROM shop_flat_table
WHERE shop_id IN (select id from workers where shop=shopName)
AND flat_txt='openhour';
IF ( NOT FOUND ) THEN
RAISE DEBUG 'opening_hour for % is null',shopName;
RETURN QUERY EXECUTE 'SELECT opened FROM stupid_bool_table WHERE opened=true'; -- by DEFAULT
-- RAISE EXCEPTION 'cant be here'; -- could be !
ELSE
RAISE DEBUG 'opening_hour for % is % (before replace)',shopName,openhour;
openhour:=REPLACE(openhour,'dow', extract(dow from NOW())::text);
openhour:=REPLACE(openhour,'hour',extract(hour from NOW())::text);
RAISE DEBUG 'opening_hour for % is % (after replace)',shopName,openhour;
RETURN QUERY EXECUTE 'SELECT opened FROM stupid_bool_table WHERE opened=' || openhour;
END IF;
END;
$BODY$
LANGUAGE plpgsql IMMUTABLE
COST 100;
所以现在: 与数据:
shop | opening_hours
------+------------------------------------------------------
ShopA | ((dow between 1 and 5) and (hour between 9 and 16)))
ShowB | ((dow between 1 and 5) and (hour between 9 and 17)))
SELECT * FROM grab_worker_test_opening_hour('ShopB');
psql:batch_workers.psql:124: DEBUG: opening_hour for ShopB is ((dow between 1 and 5) and (hour between 9 and 17)) OR (dow in (6,7)) (before replace)
psql:batch_workers.psql:124: DEBUG: opening_hour for ShopB is ((3 between 1 and 5) and (17 between 9 and 17)) OR (3 in (6,7)) (after replace)
opened
--------
t
(1 ligne)
(并在同一时间为shopA打开了= f:2018-07-25 17:15:00(等时))。