使用 CTE 对 FROM 子句条目的无效引用
invalid reference to FROM-clause entry with CTE
我正在尝试编写查询来生成时间段,但出现错误:
ERROR: invalid reference to FROM-clause entry for table "prop"
Hint: There is an entry for table "prop", but it cannot be referenced from this part of the query.
Position: 346
查询是:
WITH prop AS (SELECT p.stagger, p.tariff FROM core_property p WHERE p.id = 1)
SELECT day + (hour.a * INTERVAL '1 hour') AS time,
day + (hour.b * INTERVAL '1 hour') AS timeEnd
FROM prop,
GENERATE_SERIES(date '2022-05-18' + prop.stagger, date '2022-05-20', '1 day'::INTERVAL) day,
(SELECT UNNEST(CASE
WHEN prop.tariff = 'Economy 7' THEN ARRAY [0,12,18]
WHEN prop.tariff = 'Economy 10' THEN ARRAY [0] END) a,
UNNEST(CASE
WHEN prop.tariff = 'Economy 7' THEN ARRAY [5,13,20]
WHEN prop.tariff = 'Economy 10' THEN ARRAY [7] END) b) hour;
我有这个查询的一个版本,它几乎可以工作,但会生成重复项并且很丑陋:
SELECT day + p.stagger + (CASE
WHEN p.tariff = 'Economy 7' THEN e7.a
WHEN p.tariff = 'Economy 10' THEN e10.a END) * INTERVAL '1 hour' AS time,
day + p.stagger + (CASE
WHEN p.tariff = 'Economy 7' THEN e7.b
WHEN p.tariff = 'Economy 10' THEN e10.b END) * INTERVAL '1 hour' AS timeEnd
FROM GENERATE_SERIES(date '2022-05-18', date '2022-05-20', '1 day'::INTERVAL) day,
(SELECT UNNEST(ARRAY [0,13,20]) a, UNNEST(ARRAY [5,16,22]) b) e10,
(SELECT UNNEST(ARRAY [0]) a, UNNEST(ARRAY [7]) b) e7,
(SELECT p.stagger, p.tariff FROM core_property p WHERE p.id = 1) p;
当p.tariff = 'Economy 7'时,结果是这样的,但每天应该只有一个条目:
+---------------------------------+---------------------------------+
|time |timeend |
+---------------------------------+---------------------------------+
|2022-05-18 00:15:00.000000 +00:00|2022-05-18 07:15:00.000000 +00:00|
|2022-05-18 00:15:00.000000 +00:00|2022-05-18 07:15:00.000000 +00:00|
|2022-05-18 00:15:00.000000 +00:00|2022-05-18 07:15:00.000000 +00:00|
|2022-05-19 00:15:00.000000 +00:00|2022-05-19 07:15:00.000000 +00:00|
|2022-05-19 00:15:00.000000 +00:00|2022-05-19 07:15:00.000000 +00:00|
|2022-05-19 00:15:00.000000 +00:00|2022-05-19 07:15:00.000000 +00:00|
|2022-05-20 00:15:00.000000 +00:00|2022-05-20 07:15:00.000000 +00:00|
|2022-05-20 00:15:00.000000 +00:00|2022-05-20 07:15:00.000000 +00:00|
|2022-05-20 00:15:00.000000 +00:00|2022-05-20 07:15:00.000000 +00:00|
+---------------------------------+---------------------------------+
当p.tariff = 'Economy 10'那么结果是对的:
+---------------------------------+---------------------------------+
|time |timeend |
+---------------------------------+---------------------------------+
|2022-05-18 00:15:00.000000 +00:00|2022-05-18 05:15:00.000000 +00:00|
|2022-05-18 13:15:00.000000 +00:00|2022-05-18 16:15:00.000000 +00:00|
|2022-05-18 20:15:00.000000 +00:00|2022-05-18 22:15:00.000000 +00:00|
|2022-05-19 00:15:00.000000 +00:00|2022-05-19 05:15:00.000000 +00:00|
|2022-05-19 13:15:00.000000 +00:00|2022-05-19 16:15:00.000000 +00:00|
|2022-05-19 20:15:00.000000 +00:00|2022-05-19 22:15:00.000000 +00:00|
|2022-05-20 00:15:00.000000 +00:00|2022-05-20 05:15:00.000000 +00:00|
|2022-05-20 13:15:00.000000 +00:00|2022-05-20 16:15:00.000000 +00:00|
|2022-05-20 20:15:00.000000 +00:00|2022-05-20 22:15:00.000000 +00:00|
+---------------------------------+---------------------------------+
我不确定我是否真的需要 CTE,但这似乎是在 FROM 子句中使用 prop.tariff 和 prop.stagger 的唯一方法。
FROM/JOIN 列表中的子查询不能引用 FROM/JOIN 列表中的其他表,除非连接声明为 lateral
。所以将其声明为 LATERAL.
WITH prop AS (SELECT p.stagger, p.tariff FROM core_property p WHERE p.id = 1)
SELECT day + (hour.a * INTERVAL '1 hour') AS time,
day + (hour.b * INTERVAL '1 hour') AS timeEnd
FROM prop,
GENERATE_SERIES(date '2022-05-18' + prop.stagger, date '2022-05-20', '1 day'::INTERVAL) day,
LATERAL (SELECT UNNEST(CASE
WHEN prop.tariff = 'Economy 7' THEN ARRAY [0,12,18]
WHEN prop.tariff = 'Economy 10' THEN ARRAY [0] END) a,
UNNEST(CASE
WHEN prop.tariff = 'Economy 7' THEN ARRAY [5,13,20]
WHEN prop.tariff = 'Economy 10' THEN ARRAY [7] END) b) hour;
一个例外是 FROM/JOIN 列表中使用的裸 set-returning 函数,它被隐式地视为横向函数。这就是为什么 `generate_series(...) 不会抛出相同的错误。
我正在尝试编写查询来生成时间段,但出现错误:
ERROR: invalid reference to FROM-clause entry for table "prop"
Hint: There is an entry for table "prop", but it cannot be referenced from this part of the query.
Position: 346
查询是:
WITH prop AS (SELECT p.stagger, p.tariff FROM core_property p WHERE p.id = 1)
SELECT day + (hour.a * INTERVAL '1 hour') AS time,
day + (hour.b * INTERVAL '1 hour') AS timeEnd
FROM prop,
GENERATE_SERIES(date '2022-05-18' + prop.stagger, date '2022-05-20', '1 day'::INTERVAL) day,
(SELECT UNNEST(CASE
WHEN prop.tariff = 'Economy 7' THEN ARRAY [0,12,18]
WHEN prop.tariff = 'Economy 10' THEN ARRAY [0] END) a,
UNNEST(CASE
WHEN prop.tariff = 'Economy 7' THEN ARRAY [5,13,20]
WHEN prop.tariff = 'Economy 10' THEN ARRAY [7] END) b) hour;
我有这个查询的一个版本,它几乎可以工作,但会生成重复项并且很丑陋:
SELECT day + p.stagger + (CASE
WHEN p.tariff = 'Economy 7' THEN e7.a
WHEN p.tariff = 'Economy 10' THEN e10.a END) * INTERVAL '1 hour' AS time,
day + p.stagger + (CASE
WHEN p.tariff = 'Economy 7' THEN e7.b
WHEN p.tariff = 'Economy 10' THEN e10.b END) * INTERVAL '1 hour' AS timeEnd
FROM GENERATE_SERIES(date '2022-05-18', date '2022-05-20', '1 day'::INTERVAL) day,
(SELECT UNNEST(ARRAY [0,13,20]) a, UNNEST(ARRAY [5,16,22]) b) e10,
(SELECT UNNEST(ARRAY [0]) a, UNNEST(ARRAY [7]) b) e7,
(SELECT p.stagger, p.tariff FROM core_property p WHERE p.id = 1) p;
当p.tariff = 'Economy 7'时,结果是这样的,但每天应该只有一个条目:
+---------------------------------+---------------------------------+
|time |timeend |
+---------------------------------+---------------------------------+
|2022-05-18 00:15:00.000000 +00:00|2022-05-18 07:15:00.000000 +00:00|
|2022-05-18 00:15:00.000000 +00:00|2022-05-18 07:15:00.000000 +00:00|
|2022-05-18 00:15:00.000000 +00:00|2022-05-18 07:15:00.000000 +00:00|
|2022-05-19 00:15:00.000000 +00:00|2022-05-19 07:15:00.000000 +00:00|
|2022-05-19 00:15:00.000000 +00:00|2022-05-19 07:15:00.000000 +00:00|
|2022-05-19 00:15:00.000000 +00:00|2022-05-19 07:15:00.000000 +00:00|
|2022-05-20 00:15:00.000000 +00:00|2022-05-20 07:15:00.000000 +00:00|
|2022-05-20 00:15:00.000000 +00:00|2022-05-20 07:15:00.000000 +00:00|
|2022-05-20 00:15:00.000000 +00:00|2022-05-20 07:15:00.000000 +00:00|
+---------------------------------+---------------------------------+
当p.tariff = 'Economy 10'那么结果是对的:
+---------------------------------+---------------------------------+
|time |timeend |
+---------------------------------+---------------------------------+
|2022-05-18 00:15:00.000000 +00:00|2022-05-18 05:15:00.000000 +00:00|
|2022-05-18 13:15:00.000000 +00:00|2022-05-18 16:15:00.000000 +00:00|
|2022-05-18 20:15:00.000000 +00:00|2022-05-18 22:15:00.000000 +00:00|
|2022-05-19 00:15:00.000000 +00:00|2022-05-19 05:15:00.000000 +00:00|
|2022-05-19 13:15:00.000000 +00:00|2022-05-19 16:15:00.000000 +00:00|
|2022-05-19 20:15:00.000000 +00:00|2022-05-19 22:15:00.000000 +00:00|
|2022-05-20 00:15:00.000000 +00:00|2022-05-20 05:15:00.000000 +00:00|
|2022-05-20 13:15:00.000000 +00:00|2022-05-20 16:15:00.000000 +00:00|
|2022-05-20 20:15:00.000000 +00:00|2022-05-20 22:15:00.000000 +00:00|
+---------------------------------+---------------------------------+
我不确定我是否真的需要 CTE,但这似乎是在 FROM 子句中使用 prop.tariff 和 prop.stagger 的唯一方法。
FROM/JOIN 列表中的子查询不能引用 FROM/JOIN 列表中的其他表,除非连接声明为 lateral
。所以将其声明为 LATERAL.
WITH prop AS (SELECT p.stagger, p.tariff FROM core_property p WHERE p.id = 1)
SELECT day + (hour.a * INTERVAL '1 hour') AS time,
day + (hour.b * INTERVAL '1 hour') AS timeEnd
FROM prop,
GENERATE_SERIES(date '2022-05-18' + prop.stagger, date '2022-05-20', '1 day'::INTERVAL) day,
LATERAL (SELECT UNNEST(CASE
WHEN prop.tariff = 'Economy 7' THEN ARRAY [0,12,18]
WHEN prop.tariff = 'Economy 10' THEN ARRAY [0] END) a,
UNNEST(CASE
WHEN prop.tariff = 'Economy 7' THEN ARRAY [5,13,20]
WHEN prop.tariff = 'Economy 10' THEN ARRAY [7] END) b) hour;
一个例外是 FROM/JOIN 列表中使用的裸 set-returning 函数,它被隐式地视为横向函数。这就是为什么 `generate_series(...) 不会抛出相同的错误。