SQLite: Using count in triggers to update another column
-
15-03-2021 - |
Question
UPDATE: Fixed. Not 100% sure why sqlfiddle.com didn't like my syntax, but using https://dbfiddle.uk/?rdbms=sqlite_3.27 worked. I did change the last WHERE
clause to be based on the id
column, so that it only updates the current record, and increments instead of storing max() on records for username
.
I'm trying and failing to do something similar as described here (but in SQLite): Using count in triggers to update another table.
I assume a trigger is the best way to achieve what I want, but am open to alternate suggestions. My SQL experience is... limited, to say the least.
My goal is to have one column with an identifier, say username
and another column that is a count of the times username
is in the database at the time of the record insertion.
id | username | u_cnt | etc
1 | MarkC | 0 | ...
2 | PeterB | 0 | ...
3 | MarkC | 1 | ...
Here's a sample of what I've been trying:
create trigger count_user
after insert on rec_info
begin
update rec_info set u_cnt = ( select count(*) from rec_info where username = new.username );
end
I've been bashing my head against the docs at https://sqlite.org/lang_createtrigger.html#syntax_restrictions_on_update_delete_and_insert_statements_within_triggers
but I can't seem to figure out what's wrong with the count_user
statement. Depending on where I'm testing it I'll get one of the following
near ")": syntax error
or could not prepare statement (1 incomplete input)
, neither of which are that useful to me.
I've also tried making u_cnt
a generated/computed column ( https://sqlite.org/gencol.html ), but trying to declare the column with:
u_cnt int as (count(username)) stored,
Which gives me misuse of aggregate function count()
and trying to add HAVING
or GROUP BY
led me down a rabbit hole that gave me and headache and didn't seem to lead to progress.
Solution
Your error i can't reproduce, but i think you want this for your trigger.
MAX(u_cnt) + 1
can also be used as long as the insert only uses 0
for u_cnt
CREATE TABLE rec_info ("id" INTEGER, "username" TEXT(6), "u_cnt" TEXT(6)) ;
create trigger count_user after insert on rec_info begin update rec_info set u_cnt = ( select COUNT(*) from rec_info where username = new.username) WHERE username = new.username; end
INSERT INTO rec_info ("id", "username", "u_cnt") VALUES (1, 'MarkC', '0') ;
INSERT INTO rec_info ("id", "username", "u_cnt") VALUES (2, 'PeterB', '0') ;
INSERT INTO rec_info ("id", "username", "u_cnt") VALUES (3, 'MarkC', '0') ;
INSERT INTO rec_info ("id", "username", "u_cnt") VALUES (4, 'MarkC', '0') ;
SELECT * FROM rec_info
id | username | u_cnt -: | :------- | :---- 1 | MarkC | 3 2 | PeterB | 1 3 | MarkC | 3 4 | MarkC | 3
db<>fiddle here