嵌套的Case语句类型错误(postgres)

时间:2015-12-03 22:56:47

标签: sql postgresql pgadmin

我有一些我创建的postgres代码,它给了我一个错误:

ERROR:  CASE types character varying and numeric cannot be matched

CODE:

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。

在第二和第三栏中,创作是问题发生的地方。我假设我收到错误,因为它引用varchar的情况的第一部分,但第二种情况的结果是数字。我想使用条件" ERROR"选择要使用的数字值。

我是postgres的新手(9.4.5)但是相当精通sql。我在Windows机器上使用pgAdmin(v.1.18.1)。

我查看了我的问题的其他实例,但他们没有考虑嵌套语句。 What's wrong with my CASE?

从PGAdmin中的SQL窗格创建表current_condition的CODE:

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的代码表:

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的答案是对的。虽然列中的值是数字,但由于某种原因,表格将它们作为字符。必须自我导入。

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

错误的直接原因是数据类型不匹配,正如错误消息所示。

  

在第二和第三栏中,创作是出现问题的地方。

CASE表达式的所有可能结果都需要共享兼容的数据类型,因此必须匹配,但显然不能。 The manual instructs:

  

所有 结果 表达式的数据类型必须可转换为   单输出类型。有关详细信息,请参阅Section 10.5

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

d.ecosite3
c.ecosite2
b.ecosite

d.ecophase3
c.ecophase2
b.ecophase

更好的查询

等待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';

数据类型仍必须匹配。

如何?

这不仅更短,而且可能更快。

如果boreal_mixedwood_labeled开始,则只能第二次加入b.condition = 'ERROR'

然后你可以使用更简单的COALESCE表达式:d.*为NULL,除非我们需要它,c.*也是如此。返回第一个非空值。

如果boreal_mixedwood_labeled中的某些列可以为NULL,则逻辑可能会中断。这一切都取决于...田田! ...您的实际表格定义。 (我已经提到了吗?)不要忘记在下一个问题中加入它......