You can't use check constraints on subqueries for this. You can, however, use triggers. A simple use of row-level trigger on a table selecting from the same table and raising an exception on count > 4
would result in ORA-4901, so you'd need composite triggers for this. But that is a bit of overkill already.
So, I suggest that you might use a separate table with aggregated counts of user_ids updated via trigger and check-constrain that count. Source code:
create table user_aggr
(
user_id integer not null primary key,
user_count integer not null check (user_count <= 4)
);
You'll need to create a foreign key reference to the user_aggr
table on your user table (named user_registration
in my example):
create table user_registration
(
registration_id integer primary key,
user_id integer references user_aggr
);
... or just creating the FK constraint ...
alter table user_registration
add constraint FK_user_registration (user_id)
references user_aggr;
... plus the necessary index over the FK ...
create index user_registration_i0
on user_registration (user_id);
Then you'll need the calculation trigger:
create or replace trigger auto_user_counter
after insert or delete or update of user_id
on user_registration
for each row
begin
if updating or deleting then
merge into user_aggr T
using dual
on ( T.user_id = :old.user_id )
when matched then
update set T.user_count = T.user_count - 1
delete where T.user_count = 0
;
end if;
if inserting or updating then
merge into user_aggr T
using dual
on ( T.user_id = :new.user_id )
when matched then
update set T.user_count = T.user_count + 1
when not matched then
insert (user_id, user_count) values (:new.user_id, 1)
;
end if;
end;
/
And now you're all set and ready to rumble. Examples ...
insert into user_registration (registration_id, user_id) values(1, 1); -- OK
insert into user_registration (registration_id, user_id) values(2, 1); -- OK
insert into user_registration (registration_id, user_id) values(3, 1); -- OK
insert into user_registration (registration_id, user_id) values(4, 1); -- OK
insert into user_registration (registration_id, user_id) values(5, 1); -- ERROR
insert into user_registration (registration_id, user_id) values(11, 2); -- OK
insert into user_registration (registration_id, user_id) values(12, 2); -- OK
insert into user_registration (registration_id, user_id) values(13, 2); -- OK
insert into user_registration (registration_id, user_id) values(14, 2); -- OK
insert into user_registration (registration_id, user_id) values(15, 2); -- ERROR
delete from user_registration where user_id = 2 and rownum <= 1; -- OK; user_id 1: 4 rows; user_id 2: 3 rows
update user_registration set user_id = 2 where user_id = 1 and rownum <= 1; -- OK; user_id 1: 3 rows; user_id 2: 4 rows
update user_registration set user_id = 2 where user_id = 1 and rownum <= 1; -- ERROR on user_id 4