Nested Case statement type error (postgres)

前端 未结 2 1263
春和景丽
春和景丽 2021-01-25 18:06

I have some postgres code I have created that is giving me an error:

ERROR:  CASE types character varying and numeric cannot be matched

CODE:

相关标签:
2条回答
  • 2021-01-25 18:59

    The immediate cause for the error is the data type mismatch, as the error message tells you.

    In the second and third column creations is where the problem is occurring.

    All possible results of a CASE expression need to share compatible data types so those must match but, obviously, don't. 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.

    Assuming you refer to current_condition and current_ecosite - which are actually the 6th and 7th column, these need to have matching data types:

    d.ecosite3
    c.ecosite2
    b.ecosite
    

    and:

    d.ecophase3
    c.ecophase2
    b.ecophase
    

    Better query

    Pending the missing table definition for boreal_mixedwood_labeled, my educated guess is you can radically simplify to this query:

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

    Data types must still match.

    How?

    This is not just shorter, but probably faster, too.

    Only join to boreal_mixedwood_labeled a second time if b.condition = 'ERROR' to begin with, etc.

    Then you can use a simpler COALESCE expression: d.* is NULL unless we need it, same goes for c.*. The first non-null values is returned.

    If some of the columns in boreal_mixedwood_labeled can be NULL the logic can break. It all depends on ... tada! ... your actual table definition. (Did I mention that enough already?). Don't forget to include it with your next question ...

    0 讨论(0)
  • 2021-01-25 19:05

    Try eliminating the nested case. Maybe it makes a difference to the compiler for some reason:

    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,
    ...
    
    0 讨论(0)
提交回复
热议问题