繁体   English   中英

嵌套的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生态位和相位均为数字类型。 唯一的条件是varchar。

在第二列和第三列中,就是问题所在。 我假设我遇到错误,因为在案例的第一部分中,它引用了一个varchar,但是第二种情况的结果是数值。 我想使用条件“错误”来选择要使用的数字值。

我是Postgres(9.4.5)的新手,但精通sql。 我正在Windows机器上的pgAdmin(v。1.18.1)中工作。

我看过我的问题的其他实例,但它们不考虑嵌套语句。 我的箱子有什么问题?

在PGAdmin的“ SQL”窗格中创建表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);

该boral_mixedwood_labeled表的代码:

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的答案是正确的。 虽然列中的值是数字,但出于某种原因,表中将它们作为字符。 一定是从我的导入中自动发生的。

尝试消除嵌套的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,
...

错误的直接原因是错误消息告诉您数据类型不匹配。

在第二列和第三列中,就是问题所在。

CASE表达式的所有可能结果都需要共享兼容的数据类型,因此这些数据类型必须匹配,但显然不匹配。 手册说明:

所有结果表达式的数据类型必须可转换为单个输出类型。 有关更多详细信息,请参见第10.5节

假设您引用current_conditioncurrent_ecosite实际上是第6列和第7列,则它们需要具有匹配的数据类型:

d.ecosite3
c.ecosite2
b.ecosite

和:

d.ecophase3
c.ecophase2
b.ecophase

更好的查询

在为boreal_mixedwood_labeled缺少表定义boreal_mixedwood_labeled ,我的有根据的猜测是您可以从根本上简化为以下查询:

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,则逻辑可能会中断。 这一切都取决于...多田! ...您的实际表定义 (我已经提到足够了吗?)。 不要忘记在下一个问题中包括它...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM