嵌套 Case 语句类型错误(postgres)
Nested Case statement type error (postgres)
我创建的一些 postgres 代码出现错误:
ERROR: CASE types character varying and numeric cannot be matched
代码:
CREATE TABLE current_condition_joined AS SELECT
a.id, a.geom, a.condition_join_1, a.condition_join_2, a.condition_join_3,
(CASE WHEN b.condition = 'ERROR' THEN (CASE WHEN c.condition2 = 'ERROR' THEN d.condition3
ELSE c.condition2
END)
ELSE b.condition
END) current_condition,
(CASE WHEN b.condition= 'ERROR' THEN (CASE WHEN c.condition2 = 'ERROR' THEN d.ecosite3
ELSE c.ecosite2
END)
ELSE b.ecosite
END) current_ecosite,
(CASE WHEN b.condition = 'ERROR' THEN (CASE WHEN c.condition2 = 'ERROR' THEN d.ecophase3
ELSE c.ecophase2
END)
ELSE b.ecophase
END) current_ecophase,
(CASE WHEN b.condition = 'ERROR' THEN (CASE WHEN c.condition2 = 'ERROR' THEN d.consite3
ELSE c.consite2
END)
ELSE b.consite
END) current_consite,
(CASE WHEN b.condition = 'ERROR' THEN (CASE WHEN c.condition2 = 'ERROR' THEN d.conphase3
ELSE c.conphase2
END)
ELSE b.conphase
END) current_conphase
FROM current_condition a, boreal_mixedwood_labeled b, boreal_mixedwood_labeled c, boreal_mixedwood_labeled d
WHERE a.label = b.label_join_1
and a.label2 = c.label_join_2
and a.label3 = d.label_join_3;
b、c、d ecosite和phase均为数值型。唯一条件是 varchar.
第二列和第三列creations是出现问题的地方。我假设我收到错误,因为在案例的第一部分它引用了一个 varchar,但第二个案例的结果是数字。我想使用条件 "ERROR" 来 select 要使用的数值。
我是 postgres (9.4.5) 的新手,但相当精通 sql。我在 windows 机器上使用 pgAdmin (v. 1.18.1) 工作。
我查看了我的问题的其他实例,但它们没有考虑嵌套语句。
What's wrong with my CASE?
从 PGAdmin 中的 SQL 窗格创建 table current_condition 的代码:
CREATE TABLE current_condition (
geom geometry,
condition_join_1 text,
condition_join_2 text,
condition_join_3 text,
id serial NOT NULL,
CONSTRAINT current_condition_pkey PRIMARY KEY (id)
);
CREATE INDEX idx_current_condition_geom
ON current_condition USING gist (geom);
boreal_mixedwood_labeled TABLE 的代码:
CREATE TABLE boreal_mixedwood_labeled
(
objectid serial NOT NULL,
label character varying(255),
label2 character varying(255),
label3 character varying(255),
condition character varying(255),
ecophase numeric(15,6),
ecosite numeric(15,6),
conphase character varying(255),
consite character varying(255),
condition2 character varying(255),
ecophase2 numeric(15,6),
ecosite2 numeric(15,6),
conphase2 character varying(255),
consite2 character varying(255),
condition3 character varying(255),
ecophase3 numeric(15,6),
ecosite3 numeric(15,6),
conphase3 character varying(255),
consite3 character varying(255),
CONSTRAINT boreal_mixedwood_labeled_pkey PRIMARY KEY (objectid)
ERWIN 的回答是正确的。虽然列中的值是数字,但 table 出于某种原因将它们作为字符。一定是我导入时自动发生的。
错误消息告诉您,错误的直接原因是数据类型不匹配。
In the second and third column creations is where the problem is occurring.
CASE
表达式的所有可能结果需要共享兼容的数据类型,因此它们必须匹配,但显然不匹配。 The manual instructs:
The data types of all the result expressions must be convertible to a
single output type. See Section 10.5 for more details.
假设您引用 current_condition
和 current_ecosite
- 它们实际上是第 6 和第 7 列,它们需要具有匹配的数据类型:
d.ecosite3
c.ecosite2
b.ecosite
和:
d.ecophase3
c.ecophase2
b.ecophase
更好的查询
等待 boreal_mixedwood_labeled
的缺失 table 定义,我有根据的猜测是您可以从根本上简化此查询:
SELECT a.id, a.geom, a.condition_join_1, a.condition_join_2, a.condition_join_3
, COALESCE(d.condition3, c.condition2, b.condition) AS current_condition
, COALESCE(d.ecosite3, c.ecosite2, b.ecosite) AS current_ecosite
, COALESCE(d.ecophase3, c.ecophase2, b.ecophase) AS current_ecophase
, COALESCE(d.consite3, c.consite2, b.consite) AS current_consite
, COALESCE(d.conphase3, c.conphase2, b.conphase) AS current_conphase
FROM current_condition a
LEFT JOIN boreal_mixedwood_labeled b ON a.label = b.label_join_1
LEFT JOIN boreal_mixedwood_labeled c ON a.label2 = c.label_join_2
AND b.condition = 'ERROR'
LEFT JOIN boreal_mixedwood_labeled d ON a.label3 = d.label_join_3
AND c.condition2 = 'ERROR';
数据类型仍必须匹配。
如何?
这不仅更短,而且可能更快。
仅在 b.condition = 'ERROR'
开始时才第二次加入 boreal_mixedwood_labeled
,等等
然后你可以使用更简单的COALESCE
表达式:d.*
除非我们需要,否则为NULL,c.*
也是如此。返回第一个非空值。
如果 boreal_mixedwood_labeled
中的某些列可以为 NULL,则逻辑可能会中断。这一切都取决于...... tada! ...您的实际table定义。 (我已经提够了吗?)。不要忘记将其包含在您的下一个问题中...
尝试消除嵌套 case
。也许由于某种原因它对编译器产生了影响:
CASE
WHEN b.condition = 'ERROR' AND c.condition2 = 'ERROR' THEN d.condition3
WHEN b.condition = 'ERROR' THEN c.condition2
ELSE c.condition
END as current_condition,
...
我创建的一些 postgres 代码出现错误:
ERROR: CASE types character varying and numeric cannot be matched
代码:
CREATE TABLE current_condition_joined AS SELECT
a.id, a.geom, a.condition_join_1, a.condition_join_2, a.condition_join_3,
(CASE WHEN b.condition = 'ERROR' THEN (CASE WHEN c.condition2 = 'ERROR' THEN d.condition3
ELSE c.condition2
END)
ELSE b.condition
END) current_condition,
(CASE WHEN b.condition= 'ERROR' THEN (CASE WHEN c.condition2 = 'ERROR' THEN d.ecosite3
ELSE c.ecosite2
END)
ELSE b.ecosite
END) current_ecosite,
(CASE WHEN b.condition = 'ERROR' THEN (CASE WHEN c.condition2 = 'ERROR' THEN d.ecophase3
ELSE c.ecophase2
END)
ELSE b.ecophase
END) current_ecophase,
(CASE WHEN b.condition = 'ERROR' THEN (CASE WHEN c.condition2 = 'ERROR' THEN d.consite3
ELSE c.consite2
END)
ELSE b.consite
END) current_consite,
(CASE WHEN b.condition = 'ERROR' THEN (CASE WHEN c.condition2 = 'ERROR' THEN d.conphase3
ELSE c.conphase2
END)
ELSE b.conphase
END) current_conphase
FROM current_condition a, boreal_mixedwood_labeled b, boreal_mixedwood_labeled c, boreal_mixedwood_labeled d
WHERE a.label = b.label_join_1
and a.label2 = c.label_join_2
and a.label3 = d.label_join_3;
b、c、d ecosite和phase均为数值型。唯一条件是 varchar.
第二列和第三列creations是出现问题的地方。我假设我收到错误,因为在案例的第一部分它引用了一个 varchar,但第二个案例的结果是数字。我想使用条件 "ERROR" 来 select 要使用的数值。
我是 postgres (9.4.5) 的新手,但相当精通 sql。我在 windows 机器上使用 pgAdmin (v. 1.18.1) 工作。
我查看了我的问题的其他实例,但它们没有考虑嵌套语句。 What's wrong with my CASE?
从 PGAdmin 中的 SQL 窗格创建 table current_condition 的代码:
CREATE TABLE current_condition (
geom geometry,
condition_join_1 text,
condition_join_2 text,
condition_join_3 text,
id serial NOT NULL,
CONSTRAINT current_condition_pkey PRIMARY KEY (id)
);
CREATE INDEX idx_current_condition_geom
ON current_condition USING gist (geom);
boreal_mixedwood_labeled TABLE 的代码:
CREATE TABLE boreal_mixedwood_labeled
(
objectid serial NOT NULL,
label character varying(255),
label2 character varying(255),
label3 character varying(255),
condition character varying(255),
ecophase numeric(15,6),
ecosite numeric(15,6),
conphase character varying(255),
consite character varying(255),
condition2 character varying(255),
ecophase2 numeric(15,6),
ecosite2 numeric(15,6),
conphase2 character varying(255),
consite2 character varying(255),
condition3 character varying(255),
ecophase3 numeric(15,6),
ecosite3 numeric(15,6),
conphase3 character varying(255),
consite3 character varying(255),
CONSTRAINT boreal_mixedwood_labeled_pkey PRIMARY KEY (objectid)
ERWIN 的回答是正确的。虽然列中的值是数字,但 table 出于某种原因将它们作为字符。一定是我导入时自动发生的。
错误消息告诉您,错误的直接原因是数据类型不匹配。
In the second and third column creations is where the problem is occurring.
CASE
表达式的所有可能结果需要共享兼容的数据类型,因此它们必须匹配,但显然不匹配。 The manual instructs:
The data types of all the result expressions must be convertible to a single output type. See Section 10.5 for more details.
假设您引用 current_condition
和 current_ecosite
- 它们实际上是第 6 和第 7 列,它们需要具有匹配的数据类型:
d.ecosite3
c.ecosite2
b.ecosite
和:
d.ecophase3
c.ecophase2
b.ecophase
更好的查询
等待 boreal_mixedwood_labeled
的缺失 table 定义,我有根据的猜测是您可以从根本上简化此查询:
SELECT a.id, a.geom, a.condition_join_1, a.condition_join_2, a.condition_join_3
, COALESCE(d.condition3, c.condition2, b.condition) AS current_condition
, COALESCE(d.ecosite3, c.ecosite2, b.ecosite) AS current_ecosite
, COALESCE(d.ecophase3, c.ecophase2, b.ecophase) AS current_ecophase
, COALESCE(d.consite3, c.consite2, b.consite) AS current_consite
, COALESCE(d.conphase3, c.conphase2, b.conphase) AS current_conphase
FROM current_condition a
LEFT JOIN boreal_mixedwood_labeled b ON a.label = b.label_join_1
LEFT JOIN boreal_mixedwood_labeled c ON a.label2 = c.label_join_2
AND b.condition = 'ERROR'
LEFT JOIN boreal_mixedwood_labeled d ON a.label3 = d.label_join_3
AND c.condition2 = 'ERROR';
数据类型仍必须匹配。
如何?
这不仅更短,而且可能更快。
仅在 b.condition = 'ERROR'
开始时才第二次加入 boreal_mixedwood_labeled
,等等
然后你可以使用更简单的COALESCE
表达式:d.*
除非我们需要,否则为NULL,c.*
也是如此。返回第一个非空值。
如果 boreal_mixedwood_labeled
中的某些列可以为 NULL,则逻辑可能会中断。这一切都取决于...... tada! ...您的实际table定义。 (我已经提够了吗?)。不要忘记将其包含在您的下一个问题中...
尝试消除嵌套 case
。也许由于某种原因它对编译器产生了影响:
CASE
WHEN b.condition = 'ERROR' AND c.condition2 = 'ERROR' THEN d.condition3
WHEN b.condition = 'ERROR' THEN c.condition2
ELSE c.condition
END as current_condition,
...