我有一个名为Stores
的表,其中有一个名为store_id
的密钥和一个名为Sales
的表,其中包含store_id
引用和一个名为{{1}的json字段}。
sales_json
看起来像这样:
sales_json
我有一个plpgsql函数,其中我试图确定商店当前是否有销售,并在结果表中存储一个名为[{'start_date': '2-20-15', 'end_date': '2-21-15', 'start_time': '11:00 AM',
'end_time': '11:00 PM', 'discount_percentage': 20}, etc]
的布尔值,具体取决于是否为真。< / p>
我的SELECT语句如下所示:
having_sale
代码对我来说是正确的,但我收到以下错误:
SELECT Stores.store_id,
CASE WHEN (SELECT COUNT(*)
FROM (SELECT *
FROM json_array_elements(sales_json) AS sale
WHERE (now()::date BETWEEN (sale->>'start_date')::date AND
(sale->>'end_date')::date) AND
(now()::time BETWEEN (sale->>'start_time')::time AND
(sale->>'end_time')::time)
) AS current_sales) > 0
THEN TRUE
ELSE FALSE
END) AS having_sale
FROM Stores INNER JOIN Sales
ON Stores.store_id = Sales.store_id;
我做错了什么以及如何解决?
答案 0 :(得分:1)
错误是由我编写的函数引起的,该函数将json数组附加到sales_json
。我修好了,现在它看起来像这样:
CREATE OR REPLACE FUNCTION add_sales (insertion_id smallint, new_sales_json json)
RETURNS void AS $$
BEGIN
UPDATE Sales
SET sales_json = array_to_json(ARRAY(SELECT * FROM json_array_elements(sales_json)
UNION ALL SELECT json_array_elements(new_sales_json)))
WHERE store_id = insertion_id;
END;
$$ LANGUAGE plpgsql;
我以前错过了对new_sales_json的json_array_elements()
调用,这就是为什么我在数组中得到一个数组,因此cannot extract field from a non-object
错误。
答案 1 :(得分:0)
除了您自己整理的mix-up of element and array input之外,您还可以在很大程度上简化SELECT
声明:
SELECT store_id
, EXISTS (
SELECT 1
FROM json_array_elements(s.sales_json) sale
WHERE now() BETWEEN (sale->>'start_date')::date + (sale->>'start_time')::time
AND (sale->>'end_date')::date + (sale->>'end_time')::time
) AS having_sale
FROM Stores st
JOIN Sales s USING (store_id);
更短更快。
添加时间和日期会产生timestamp [without time zone]
。最好存储时间戳数据而不是日期和时间。
除非您的时间是每日时间表,否则不是与日期相结合的绝对范围。然后你必须保留原始表达。
最后,BETWEEN
包含两个边界,而您通常包含下限,排除上限:
WHERE now() >= (sale->>'start_date')::date + (sale->>'start_time')::time
AND now() < (sale->>'end_date')::date + (sale->>'end_time')::time
请注意,您的日期和时间将根据时区的当前设置进行解释。