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.

Was it helpful?

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

Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange
scroll top