PostgreSQL - 在case语句中将整数值赋给string

时间:2017-02-09 23:35:53

标签: sql postgresql

我需要根据我拥有的数据中的ID选择一行且只有一行数据。我以为我已经解决了这个问题(有关详细信息,请参阅我原来的问题和我的解决方案,在这里:PostgreSQL - Select only 1 row for each ID

但是,在某些情况下,我现在仍然会获得多个值。如果只有“N / A”和另外1个值,那么没问题..但如果我有多个值,例如:“N / A”例如,“value1”“value2”,那么我的案例陈述是不够的,我得到“value1”“value2”< / strong>回到我身边。这是有问题的案例陈述:

CASE
    WHEN "PQ"."Value" = 'N/A' THEN 1
    ELSE 0
END

我需要为每个字符串值赋一个唯一的整数值,然后问题就解决了。问题是:我该怎么做?我的第一个想法是以某种方式将字符值转换为ASCII并总结它们。但我不知道该怎么做并且还担心性能。有没有办法非常简单地为每个字符串赋值,以便我只能选择1个值?我不关心哪一个......只是它只有1个。

修改

我现在正在尝试创建一个函数来添加每个字符的ASCII值,这样我基本上可以将我的case语句更改为:

CASE
    WHEN "PQ"."Value" = 'N/A' THEN 9999999
    ELSE SumASCII("PQ"."Value")
END

虽然有一个小问题..我已将其作为一个单独的问题添加,在这里:PostgreSQL - ERROR: query has no destination for result data

编辑2

感谢@Bohemian,我现在有了一个有效的解决方案,如下:

CASE
    WHEN "PQ"."Value" = 'N/A' THEN -1
    ELSE ('x'||LPAD(MD5("PQ"."Value"),16,'0'))::bit(64)::bigint
END DESC

2 个答案:

答案 0 :(得分:1)

这将为每个值生成一个“唯一”数字:

('x'||substr(md5("PQ"."Value"),1,8))::bit(64)::bigint

严格来说,有可能发生碰撞,但它很遥远。

如果结果“太大”,您可以尝试模数:

<above-calculation> % 10000

虽然碰撞的概率为0.01%,但您应该针对所有已知值尝试此公式,以确保没有碰撞。

答案 1 :(得分:0)

如果您不关心选择哪个值,请将RANK()更改为ROW_NUMBER()。如果你关心,无论如何都要这样做,而且还要在ORDER BY中的CASE语句之后添加另一个术语,用逗号分隔,用你想要的逻辑 - 例如,如果你想要按字母顺序排列第一个值,请执行以下操作:

...
ORDER BY CASE...END, "PQ"."Value")
...