You can use a table constraint (depending on SQL engine -- not clear which one you're using) to make sure there aren't too many tuples of a particular kind.
Under Firebird 2.1:
fb> CREATE TABLE so2587151 (
> a VARCHAR(16) NOT NULL,
> b VARCHAR(16) NOT NULL,
> c VARCHAR(1) NOT NULL CHECK (c in ('T', 'F')),
> CONSTRAINT so2587151_only_one_false CHECK ( -- begin CONSTRAINT
> NOT EXISTS ( SELECT a, b, COUNT('x')
> FROM so2587151
> WHERE c = 'F'
> GROUP BY 1, 2
> HAVING COUNT('x') >= 1 )
> ) -- end CONSTRAINT
> );
fb> INSERT INTO so2587151(a,b,c) VALUES ('foo', 'bar', 'T');
fb> INSERT INTO so2587151(a,b,c) VALUES ('foo', 'bar', 'T');
fb> INSERT INTO so2587151(a,b,c) VALUES ('foo', 'bar', 'F');
fb> INSERT INTO so2587151(a,b,c) VALUES ('foo', 'bar', 'F');
Error: Operation violates CHECK constraint on view or table
-Operation violates CHECK constraint SO2587151_ONLY_ONE_FALSE on view or table SO2587151
-At trigger 'CHECK_15'
fb> SELECT * FROM so2587151;
A | B | C
==============
foo | bar | T
foo | bar | T
foo | bar | F
As you can see from the constraint violation error message, this is implemented in terms of Firebird's trigger mechanisms under the hood.