Remove particular id from database field - php

Am storing a string separated using |, which lists the groups allowed, now my issue is if I delete a group than I am not able to remove the ID from that particular field, for example
allowed_group_id
+---------------+
1332|4545|5646|7986
So for example am deleting the group say no 5646, so how do I alter the scripts and remove that particular group from the allowed_group_id in script table?

I recommend taking the entry, exploding it by "|", removing the appropriate entry, imploding it back and updating.
$allowedGroupId = '1332|4545|5646|7986';
$parts = explode('|', $allowedGroupId);
if(($key = array_search($deleteGroup, $allowedGroupId)) !== false) {
unset($allowedGroupId[$key]);
}
$update = " ... "; //update with the new imploded values
Hope it helps

You can try this-
update table tableName set allowed_group_id = REPLACE(allowed_group_id, '5646', '');

Use explode:
$allowed_ids = explode('|', $current_allowed_group_ids);
if($remove_key = array_search($remove_id, $allowed_ids) !== false) {
unset($allowed_ids[$remove_key]);
}
$update_query = 'UPDATE table_name SET allowed_group_id = "'. implode('|', $allowed_ids) .'" WHERE id= ...';
But you might want to alter your database design slightly, creating a pivot table to check for allowed ids. Example:
+------------+
| GROUPS |
+----+-------+
| id | name |
+----+-------+
| 1 | grp_1 |
| 2 | grp_2 |
...
+--------------------+
| ALLOWED_GROUPS |
+--------------------+
| user_id | group_id |
+---------+----------+
| 2 | 1 |
| 2 | 2 |
| 5 | 2 |
...

Using Suresh response and improving it:
UPDATE TABLE tableName SET allowed_group_id = REPLACE(
REPLACE(allowed_group_id, '5646', ''),
'||',
'|');
First you search for '5646' string in allowed_group_id and replace it with empty string ''. Secondly you search and replace two bars from your result '||' with only one bar '|'. This will avoid having '1332|4545||7986' in your allowed_group_id.

Or you should have a table with 2 columns 1 with the id of the action you whant to allow and one with the id of a group.

Whilst the other answers will solve your problem as-is: you might want to consider normalising your database.
For example, if you currently have a table table_name containing id and allowed_group_id, then you would create a new table allowed_group containing multiple rows for each allowed group:
foreign_id | group_id
-----------+---------
1 | 1332
1 | 4545
1 | 5646
1 | 7986
...and so on. Here, foreign_id is the ID of the row in your existing table_name table. Now, instead of your above problem, you can simply DELETE FROM allowed_group WHERE foreign_id = 1 AND groupId = 5646.
This is called putting your data in first normal form.

Related

How to use LIKE statement to check if each value in an array is present in a SQL table? [duplicate]

I have the following example table and attributes:
---------------------------
| Name | Town |
---------------------------
| Name 1 | POOLE |
| Name 2 | POOLE/WALLASEY |
| Name 3 | POOLE/WALLASEY |
| Name 4 | POOLE |
---------------------------
I am using the following SQL statement in PHP to retrieve rows:
SELECT * FROM `table` WHERE `Town` LIKE '%".$global->getPlayerTown()."%'
Given the criteria POOLE the database returns:
---------------------------
| Name | Town |
---------------------------
| Name 1 | POOLE |
| Name 2 | POOLE/WALLASEY |
| Name 3 | POOLE/WALLASEY |
| Name 4 | POOLE |
---------------------------
However when using the criteria POOLE/WALLASEY the query returns:
---------------------------
| Name | Town |
---------------------------
| Name 2 | POOLE/WALLASEY |
| Name 3 | POOLE/WALLASEY |
---------------------------
How do I intelligently tell the PHP to split the string into separate criteria (i.e. POOLE and WALLASEY) in one query, so that the query retrieves all rows?
SELECT * FROM `table` WHERE `town` REGEXP 'POOLE|WALLASEY';
This will match any rows that has one or more instances of POOLE or WALLASEY.
As to the PHP side, depending on how many kinds of separators ('/' in this case) you have in your dataset, it can get rather messy rather quickly.
But replace '/' with '|' in getPlayerTown() would seem to be one way of doing it.
As to performance, I'm not sure how REGEXP is as opposed to LIKE.
https://dev.mysql.com/doc/refman/5.7/en/regexp.html
This is an iteration of an often-asked class of questions: How do I select on a single datum, if I have more than one in a field?
The answer, as always, is: You don't.
There are many reasons for that, but one of the most important is performance: Basically a LIKE '%...' can't use an index. That might be ok with a handful of test rows, but it quickly becomes a problem when scaling.
The only reliable ways are to
either normalize your data
or use a fulltext index
In your case I'd strongly vote for normalization: Create a towns table, then link it to the players via a join table. You can now search for any town with full index use, finding the players through the join.
As Marc B stated, using explode.
<?php
$array = explode("/",$global->getPlayerTown());
foreach($array as $Town){
$list = $list ."'%" .$Town ."%', ";
}
$SQL = "SELECT * FROM `table` WHERE `Town` LIKE ANY(" .$list .")";
?>
Please go the smart route and normalize your data. This idea may work, but that doesn't mean it is the best choice.
You could explode the towns, then loop through them and build the query like so:
$towns = explode('/', $global->getPlayerTown());
$first = true;
$like_sql = '';
foreach($towns as $town) {
$like_sql .= $first ? ' WHERE ' : ' OR ';
$like_sql .= "`Town` LIKE '%{$town}%'";
$first = false;
}
$query = "SELECT * FROM `table` {$like_sql}";
However I would recommend you normalise your data, and have a separate towns table, with a user_town pivot table.

Insert data using INSERT INTO command.

I have two table name users and users_images. Both table have the value of userId. like
My user table
| userId | userName | user_address |
| 2 | John | CN-2, UK |
| 3 | Amit | India |
| 4 | David | Us |
| 5 | Shan | Canada |
.
.
...... and so on
| 125000 | Naved | Ukran |
**and my images table contain userid and Image name.
Now I want to merge ImageName field to user table without using any loop (I want to do it with single query (I have millions of records and I will have to do it many times to create temorary table) )
update users u
set
u.imageName = (
select imageName
from users_images i
where i.userid = u.userid GROUP BY u.userId )
you could use ON DUPLICATE KEY
for instance:
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
I think you can use Update for this like:
UPDATE Users
SET ImageName =
(SELECT ImageName
FROM UserImages
WHERE UserImages.UserID = Uers.UserID)
Please take a backup of your database first

SQL optimizing query

I have a table that has the following records:
ID | Username | Selected |
----------------------------
1 | JamesC | 1 |
2 | MikeF | 0 |
3 | JamesC | 0 |
I wish to have Selected be true for only 1 row where the username is the same. So for example when I set ID = 3 to be Selected = true I wish to setID =1 to have Selected = false as well as any other ID's with the same username.
Right now i'm doing this,
//set all to 0
update table set selected = 0 where username = '$username'
//set unique row to true
update table set selected = 1 where username = '$username' and ID = '$ID';
Is there a better more concise way of achieving the same effect?
As it was said - not very nice db structure, it is better to have table with unique names and ID of selected item, anyway, you can go with this single query:
update table set selected=IF(id = '$ID', 1, 0) where username = '$username';
also, try a possible faster variant (test both via explain):
update table set selected=IF(id <> '$ID', 0, 1) where username = '$username';
It looks more like optimizing db structure to me. More info needed for concrete answer though, but check this example to see what I'm talking about:
users:
user_id | user_name | selected_character_id | ...other account data
1 | JamesC | 3
2 | MikeF | 2
characters:
character_id | user_id | ...other character data
1 | 1 |
2 | 2 |
3 | 1 |
You will need JOIN tables to retrieve all data for selected character (fast since it operates on unique ids), but get rid of data duplication (and easier switch).
You will always need the second statement, but as you only have one "Selected" row you could use:
update table set selected = 0 where selected = 1

MYSQL Update and add a value into cell

hello friends I want to update a cell in a table whit new content, but retaining the content that has. I need to add the new data separated whit comma or line break (is'nt relevant), preserving the data that have inside.
|id | title | referer|
|--------------------|
| 1 | post1 | google |
| 2 | post2 | yahoo |
| 3 | post3 | bing |
| 4 | post4 | google |
The table should look like this with new content added.
|id | title | referer |
|-------------------------------|
| 1 | post1 | google,yahoo,bing |
| 2 | post2 | yahoo,bing,etc |
| 3 | post3 | bing |
| 4 | post4 | google,google |
this is my code to insert new rows in my Database:
mysql_query("INSERT IGNORE INTO posts (id,title,referer) VALUES (null,'$q','$referer')");
What would be the code to add information in the cell "referer" whit Comma separated or line break ?
thanks in advance
I am not sure about what you might do with how separate them with commas unless you will want to create an array of variables and concat them into a single variable and use mysql's CONCAT function to update your table in order to keep your last field data:
$referes_list = '';
foreach ($referers as $referer) {
$referes_list .= $referer . ", ";
}
UPDATE referers SET referer=CONCAT(referer,'$referes_list') WHERE id='$id' ;
You'll have to forgive me if my MySQL skills aren't the greatest, but what I would do here is simply get the current value, append a comma and new value to it, then update the cell.
...Or did I misinterpret your question?
In mysql there isnt "comma separated type", that is just a simple string or VARCHAR, so, you will need get previous data and concatenate it like string in php and then update it.
I think you are looking for something like:
update t
set referrer = (case when referer is null or referer = ''
then #newvalue
else concat(referer, ',', #newvalue)
end)
where id = #id;
mysql_query('UPDATE tablename SET referer = concat(referer,", '.$value.'") where id="'.$id.'")';
this should do it, it's untested though.

Exploding in php

In my table 'users' there are 'friends' ,
Like this :
+----+------+---------+
| id | name | friends |
+----+------+---------+
| 1 | a | 0,1,2 |
| 2 | b | 0,1,3 |
| 3 | c | 0,1 |
+----+------+---------+
How do I use the explode function to get the friends id one by one (not 0,1,2) that are separated by a comma (,) ;
How do I select the id? (Example) :
$sql = Select id from users where id = (exploded)
if (mysql_num_rows($sql) > 0 ) {
$TPL->addbutton('Unfriend');
}else{
$TPL->addbutton('Add as Friend')
}
The solution here is actually a slight change in your database structure. I recommend you create a "many-to-many" relational table containing all of the users friends referenced by user.
+---------+-----------+
| user_id | firend_id |
+---------+-----------+
| 1 | 2 |
| 1 | 3 |
| 1 | 4 |
| 2 | 1 |
| 2 | 5 |
+---------+-----------+
If you are storing lists of values within one field then that is the first sign that your database design is not quite optimal. If you need to search for a numerical value, it'll always be better to place an index on that field to increase efficiency and make the database work for you and not the other way around :)
Then to find out if a user is a friend of someone, you'll query this table -
SELECT * FROM users_friends WHERE
`user_id` = CURRENT_USER AND `friend_id` = OTHER_USER
To get all the friends of a certain user you would do this -
SELECT * FROM users_friends WHERE `user_id` = CURRENT_USER
Just a simple example that will make you clear how to proceed:
// Obtain an array of single values from data like "1,2,3"...
$friends = explode(',', $row['friends']);
Then, back in your query:
// Obtain back data like "1,2,3" from an array of single values...
$frieldslist = implode(',', $friends);
$sql = "SELECT * FROM users WHERE id IN ('" . $frieldslist . "')";
to get an array of if ids from your string explode would be used like this
$my_array = explode("," , $friends);
but you'd probably be better using the mysql IN clause
$sql = "Select id from users where id in (".$row['friends'].")";
Just a quick idea. Change your database's table. It is certain that after a while many problems will arise.
You could have something like this.
id hasfriend
1 2
1 3
2 1 no need to be here (You have this already)
2 4
.....
You can do this by using indexes for uniqueness or programming. You may think of something better. Change your approach to the problem to something like this.

Categories