Removal from JSON array in MySQL - mysql

I'm managing a followers list through a JSON array. I'm using JSON_ARRAY_APPEND to add a follower:
UPDATE users
SET follows = JSON_ARRAY_APPEND(follows, '$', "followerToBeAdded")
WHERE username = "user"
However, I'm unable to remove a follower from this list. If I try JSON REMOVE, it just erases the whole JSON array instead of just removing a particular follower from the list.
Any idea of a possible query for it?

As you've added the MySQL tag in the question so the following response is inaccordance with MySQL.
Let's consider the users table with the two columns username and json column follows. Assume we've a username x and one follower a to begin with.
Let's add 2nd and 3rd follower
UPDATE users SET follows = JSON_ARRAY_APPEND(follows, '$', 'b') where username ='x';
UPDATE users SET follows = JSON_ARRAY_APPEND(follows, '$', 'c') where username ='x';
Removal: Let's say we want to remove the follower b
To check the follower to be removed
SELECT JSON_SEARCH(follows, 'one', 'b') FROM users;
Above will give path to the object to be deleted in the array.
UPDATE users SET follows = JSON_REMOVE(follows, JSON_UNQUOTE(JSON_SEARCH(follows, 'one', 'b'))) WHERE JSON_SEARCH(follows, 'one', 'b') IS NOT NULL;

Related

Adding values to existing string

This sounds like a basic stuff but I'm running our of caffeine and my brain is seizing...
I have a table with where couple columns are set as datatype = text and contain comma separated strings, something like this
id | labels | items
------------------------------------------------
123 | Resources,Faculty Resources | 2323,97
If I know row ID can I append new values to labels and items via UPDATE or do I first need to query the table, get data, append values and then do update with new string?
A single update query can do:
update mytable
set items = concat(coalesce(concat(items, ','), ''), :new_item)
where id = :id
... where :new_item is the item you want to add and :id is the id of the target row.
The coalesce()/concat() logic takes in account the possibility that items could be null on an existing row. If that's never the case, then simply:
update mytable
set items = concat(items, ',', :new_item)
where id = :id
Note, however, that storing delimited lists in a table is bad practice, and should be generally avoided. More about this can be read in this famous SO question.

How to update json type column value in mysql if I have multi array on the json string

I have a json string and I want to edit value of college key in the json. The json string given below which is normally a column value from mysql table.
So my sql query :- select subjectcombination from table where id = 10;
subjectcombination = {"subjectcombination": [{"college": "GOVT. COLLEGE FOR BOYS, REWARI", "district": "REWARI", "college_uuid": "2C533FD3546CF32D2D8D057480006BEE", "district_uuid": "914B62192C43EFB8AA203EF848054856", "course_section": "B.A I", "college_course_id": "28010"}]}
So Please let me know how can I update value of subjectcombination column value with specific college key(I want to update college value). For eg. :- update GOVT. COLLEGE FOR BOYS, REWARI to "ABC"
You can use the following solution using JSON_REPLACE:
UPDATE table_name
SET subjectcombination = JSON_REPLACE(subjectcombination, '$.subjectcombination[0].college', 'ABC')
WHERE id = 10;
You can also try the following SELECT to get a preview of the UPDATE:
SELECT JSON_REPLACE(subjectcombination, '$.subjectcombination[0].college', 'ABC')
FROM table_name;

MYSQL passing string into IN operator not working in nodejs

by right SELECT topicFollowed FROM User WHERE id = 10000) return "[0,2]" <<-string
but when i execute SELECT * from News WHERE topicId IN (SELECT topicFollowed FROM User WHERE id = 10000) only 0 is pass in and 2 is not. i cant figure out why. it only return topicId that is 0
Your IN list consists of exactly one item, a string of the form '[0,2]'. If that is what topicId looks like, then your query will work.
In other words, you have a problem with your data structure. You shouldn't be storing lists of things in strings. The proper data structure would have two rows, one for each of the ids in the list.
Sometimes, you are stuck with someone else's bad data design. You can do what you want, by doing something like this:
SELECT n.*
from News n
WHERE EXISTS (SELECT 1
FROM user u
WHERE find_in_set(topicId, replace(replace(topicFollowed, '[', ''), ']', '') AND
id = 10000
);

Building an entity join LINQ query

I have the following table strutucture and am accessing them by using MySQL Entity Framework:
Table Users
- Id
- Name
Table Subscriptions
- Id
- Id_User
- Id_Course
Table Courses
- Id
- Name
What I would like and am having a hard time to do so is building a link query for all users that returns a list with each entry containing:
User Id;
User name;
Concat string separated by comma with all courses for the user or 'no courses' string if none.
This list should be filtered by a part of users name.
I've started to build the code but can't finish it:
var Model db = new Model();
var list = from user in db.Users
join ???
where user.Name.Contains(filter.Trim())
select new { Name = user.Name, Id = user.Id, ???}
Can anyone help me please ?
You should use navigation properties (like User.Subscriptions) for this. Depending on how you created the model they may already be there, else you first should add them.
var query = from u in db.Users
where user.Name.Contains(filter) // trim the filter value first
select new
{
u.Name,
u.Id,
Courses = u.Subscriptions.Select(s => s.Course.Name)
};
var result = query.AsEnumerable()
.Select(q => new
{
q.Name,
q.Id
Courses = string.Join(", ", q.Courses)
};
The reason for doing this in two phases is that string.Join can't directly be used in an EF LINQ expression (can't be turned into SQL) so it must be done in memory (i.e. after an AsEnumerable).
But still it may be efficient to do a projection first (the first part), otherwise too much data may be fetched from the database.

MySQL Get "id" from select

I have a select statement:
SELECT id, content, name
FROM records
WHERE type = '1'
AND name = 'test';
Here's the output:
id content name
99708 10.6.252.41 server01.example.org
What I'd like to do is be able to get the id that is returned from the previous statement and USE the id as input into another statement (an UPDATE statement) that will increment the value of a single column in the same table.
An example UPDATE statement that I am wanting is:
update records SET hits = hits + 1 WHERE id = ID_FROM_SELECT;
Thanks in advance.
You can use user defined session variables for this if the SELECT is returning just one result:
SELECT #id:=id AS id, content, name
FROM records
WHERE type = '1'
AND name = 'test';
Then, on the same database session (connection), do the following:
UPDATE records
SET hits = hits + 1
WHERE id = #id;
I'm assuming you're doing something with the selected records in your app, and you're trying to save on performance by avoiding having to search for the record again in the UPDATE. Though, in that case, why not set the 'id' value as a parameter in code?
Obviously, if the SELECT is returning multiple records, this would best be done in code as I mentioned above, otherwise you're left with running the SELECT query again as a subquery:
UPDATE records
SET hits = hits + 1
WHERE id IN
(SELECT id
FROM records
WHERE type = '1'
AND name = 'test');
So, then, it makes more sense just to apply the same filter to the UPDATE instead:
UPDATE records
SET hits = hits + 1
WHERE type = '1'
AND name = 'test'
Probably this is not what you want to do.
First of all...If the query only returns 1 line, the solution provided by Marcus Adams works fine. But, if the query only returns one line, you dont need to preset the id in order to update. Just update it:
update records
set hits = hits + 1
where type = '1'
and name = 'test'
Second...If the query will not return only one record and you want to update all records returned with same values or calculations, the same code above will do what you need.
Third, if the query does not return just one record and you need to update each record returned with different value then you need to have a different approach.
I think you are not designing your system very well. If the request for update come from outside, you should have the id to be updated as a parameter of your request. For example something like:
<html>
<body>
Test
</body>
</html>
And in your update.php you have something like:
<?php
$id = $_GET['id'];
$sql = "update records set hits = hits + 1 where type = '1' and name = 'test' and id = $id";
?>
Of course, the picture I have is to small. Probably you have a reason to do this way or this is just an example. If you fill us up with more info we might be more helpful.