Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
298 views
in Technique[技术] by (71.8m points)

sql - PostgreSQL - Assign integer value to string in case statement

I need to select one and only 1 row of data based on an ID in the data I have. I thought I had solved this (For details, see my original question and my solution, here: PostgreSQL - Select only 1 row for each ID)

However, I now still get multiple values in some cases. If there is only "N/A" and 1 other value, then no problem.. but if I have multiple values like: "N/A", "value1" and "value2" for example, then my case statement is not sufficient and I get both "value1" and "value2" returned to me. This is the case statement in question:

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

I need to give a unique integer value to each string value and then the problem will be solved. The question is: how do I do this? My first thought is to somehow convert the character values to ASCII and sum them up.. but I am not sure how to do that and also worried about performance. Is there a way to very simply assign a value to each string so that I can choose 1 value only? I don't care which one actually... just that it's only 1.

EDIT

I am now trying to create a function to add up the ASCII values of each character so I can essentially change my case statement to something like this:

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

Having a small problem with it though.. I have added it as a separate question, here: PostgreSQL - ERROR: query has no destination for result data

EDIT 2

Thanks to @Bohemian, I now have a working solution, which is as follows:

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This will produce a "unique" number for each value:

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

Strictly speaking, there is a chance of a collision, but it's very remote.

If the result is "too big", you could try modulus:

<above-calculation> % 10000

Although collisions would then be a 0.01% chance, you should try this formula against all known values to ensure there are no collisions.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...