And, of course, if you want your JSON array to be in MRU order, you can use 
this:

update users as O
   set urls = (
               select json_group_array(distinct value)
                 from (
                       select ?2 as value
                      union all
                       select value
                         from json_each(urls)
                         join users
                        where userid = O.userid
                      )
              )
 where userid == ?1
   and ?2 is not null;

or

update users as O
   set urls = (
               select json_group_array(value)
                 from (
                       select ?2 as value
                      union all
                       select value
                         from json_each(urls)
                         join users
                        where userid = O.userid
                          and value != ?2
                      )
              )
 where userid == ?1
   and ?2 is not null;

or for LRU order this:

update users as O
   set urls = (
               select json_group_array(value)
                 from (
                       select value
                         from json_each(urls)
                         join users
                        where userid = O.userid
                          and value != ?2
                      union all
                       select ?2 as value
                      )
              )
 where userid == ?1
   and ?2 is not null;

The advantage of course is that you can specify a collation such as nocase for 
the "value != ?2 collate nocase" so that HttP://WwW.GooGle.Com is the same as 
http://www.google.com without having to normalcase all your URLs first ...

-- 
The fact that there's a Highway to Hell but only a Stairway to Heaven says a 
lot about anticipated traffic volume.

>-----Original Message-----
>From: sqlite-users <sqlite-users-boun...@mailinglists.sqlite.org> On
>Behalf Of Keith Medcalf
>Sent: Friday, 10 January, 2020 18:07
>To: SQLite mailing list <sqlite-users@mailinglists.sqlite.org>
>Subject: Re: [sqlite] JSON_GROUP_ARRAY unexpected misuse error in UPDATE
>
>
>On Friday, 10 January, 2020 14:35, Jason Dora <tonur...@gmail.com> wrote:
>
>>I have a workflow where I would like to push an item onto a JSON array,
>>while ensuring the items on the array are unique. And I'm able to write
>a
>>working statement in a SELECT, but the same logic fails in a UPDATE.
>
>You need to define what you mean by "push an item onto a JSON array".  Do
>you want the array to be ordered by insertion order or merely contain
>sorted distinct entries?
>
>>Assume there is a table named "users" with the columns UserId and URLs.
>>UserId being the primary key and all URLs values being well formatted
>>JSON
>>e.g. [], ["http://google.com";], etc.
>
>>Assume then I want to add "http://foobar.com"; to the URLs for UserId 1.
>
>>This SELECT will return the expected value:
>>SELECT JSON_GROUP_ARRAY((SELECT value FROM
>>JSON_EACH(JSON_SET(URLs,'$['||JSON_ARRAY_LENGTH(URLs)||']','
>>http://foobar.com')) GROUP BY value)) AS URLs FROM users WHERE UserId=1;
>
>This does not appear to actually do what you want ... at least not when I
>execute it with test data ...
>
>>Trying to UPDATE using the same pattern generates a "misuse of aggregate
>>function" error:
>>UPDATE users SET URLs=JSON_GROUP_ARRAY((SELECT value FROM
>>JSON_EACH(JSON_SET(URLs,'$['||JSON_ARRAY_LENGTH(URLs)||']','
>>http://foobar.com')) GROUP BY value)) WHERE UserId=1;
>
>That is a correct error message.
>
>JSON_GROUP_ARRAY is an aggregate function applicable to select ... it is
>not a scalar function.  It works exactly the same way all the time.
>
>The following query appends a value to the end of the array if it is not
>already in the array ...
>
>select json_group_array(distinct value)
>  from (
>        select value
>          from (
>                select value
>                  from json_each(urls)
>                  join users
>                 where userid=?
>                )
>       union all
>        values (?)
>       );
>
>and the corresponding update statement to add an arbitrary value bound as
>parameter 2 to the userid bound as parameter 1 would be:
>
>update users as O
>   set urls = (
>               select json_group_array(distinct value)
>                 from (
>                       select value
>                         from (
>                               select value
>                                 from json_each(urls)
>                                 join users
>                                where userid = O.userid
>                               )
>                      union all
>                       values (?2)
>                      )
>              )
> where userid == ?1
>   and ?2 is not null;
>
>--
>The fact that there's a Highway to Hell but only a Stairway to Heaven
>says a lot about anticipated traffic volume.
>
>
>
>_______________________________________________
>sqlite-users mailing list
>sqlite-users@mailinglists.sqlite.org
>http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users



_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to