Q:

PostgreSQL check constraint

CREATE TABLE my_table
(
    fk      INTEGER,
    field_1 INTEGER,
    field_2 INTEGER,
    field_3 INTEGER
)

VALID:

    fk    |    field_1    |    field_2    |    field_3              
----------+---------------+---------------+---------------
     1    |      1        |      null     |      null
     1    |      null     |      1        |      null
     1    |      null     |      null     |      1

It's possible to create check constraint which allows only 1 field of 3 can be not null for 1 fk ?

A:

It is not quite clear what you'd like to achieve.
If you need only one column being NOT NULL per row, then Nitram's answer will do, you can also try:
CHECK ((sign(coalesce(field_1,0)) +
        sign(coalesce(field_2,0)) + sign(coalesce(field_3,0))) <= 1)

Otherwise, if you need to have only single NOT NULL column per all rows with the given FK, you should look into the CONSTRAINT TRIGGER, something like this:
CREATE OR REPLACE FUNCTION only_one() RETURNS trigger AS $only_one$
DECLARE
    cnt  int4;
BEGIN
    SELECT sign(coalesce(field_1,0)) +
           sign(coalesce(field_2,0)) +
           sign(coalesce(field_3,0)) +
           sign(coalesce(NEW.field_1,0)) +
           sign(coalesce(NEW.field_2,0))+
           sign(coalesce(NEW.field_3,0))
      INTO cnt
      FROM my_table WHERE fk = NEW.fk;

    IF cnt > 1 THEN
        RAISE EXCEPTION 'Sorry, too much NOT NULL values for FK=%', NEW.fk;
    END IF;

    RETURN NEW;
END;
$only_one$ LANGUAGE plpgsql;
CREATE CONSTRAINT TRIGGER my_table_only_one 
 AFTER INSERT OR UPDATE ON my_table
   FOR EACH ROW EXECUTE PROCEDURE only_one();

