I have a table which contains rows, within each row there is a field which contains peoples names seperated by a double space.
I need to extract this field from each row, then split the field into separate names and dump into another table.
What's the best way to do this? Do I split it within the sql query or extract the fields then split using PHP?
New info:
OK, the field contains full names e.g. john doe, tom smith etc etc the double spaces separate the full names e.g.
JOHN DOE TOM SMITH JOHN WOO
There might be one name in the field but there could also be potentialy up to 10
Thanks
Darren
you can do it in sql. should be something like this:
INSERT INTO tbl_dest (first_name, last_name) VALUES
(SELECT
LEFT(ts.name, LOCATE(' ',ts.name)) AS first_name,
SUBSTRING(ts.name, LOCATE(' ',ts.name)+2) AS last_name
FROM tbl_source AS ts)
as #Marc B stated, it will only work if the data is consistent (ie each row's name field contains a double space and the first double space separates the name and password.
you can ignore other rows (without the double space) by simply adding
INSERT ...
(SELECT ...
FROM tbl_source AS ts WHERE LOCATE(' ', ts.name) > 0)
if the field starts with a double space (ie first name is empty) it will also be ignored
EDIT:
since you said that each row can contain multiple pairs of first/last name. here's a code example:
$query = "SELECT `name` FROM `tbl_source`";
$res = mysql_query($query, $link);
$names = array();
while ($row = mysql_fetch_assoc($res)) {
$nmlist = explode(' ',$row['name']);
for($i=0, $n=count($nmlist); $i<$n-1; $i+=2){
$names[] = "('" . mysql_real_escape_string(stripslashes($nmlist[$i])) ."',"
."'" . mysql_real_escape_string(stripslashes($nmlist[$i+1])) ."')";
}
}
$insert_query = "INSERT INTO `tbl_dest` (`first_name`,`last_name`) VALUES "
.implode(',', $names);
mysql_query($insert_query, $link);
in this example, double spaces are between first name and last name, and between each pair
I'm not familiar with a MySQL solution for this.
I suggest grabbing the information you need, using explode(' ', $info); and then inserting back into the database.
Related
A previous variable from a query gave me a value $name. I need to find the user id associated with that name, however in my users table I have two fields, firstName and lastName.
I cannot explode $name as I have both cases of double names (e.g. John Eric Smith) and last names (e.g. Jan van der Worde), so my attempt was to find a way to match firstName + lastName with $name.
My attempt was this:
$drid = "SELECT id FROM users WHERE CONCAT(firstName,' ',lastName)='$name'";
$rest = mysql_query($drid);
while ($row = mysql_fetch_row($rest)) {
$driver_id = $row[0];
}
Unfortunately, nothing comes out as a result for $driver_id (whereas $name returns a result).
Thank you for your help!
Are you looking for something like this:
<?php
$drid = "SELECT id FROM users WHERE CONCAT(firstName, ' ', lastName) LIKE '%".$name."%'";
$rest = mysql_query($drid);
while ($row = mysql_fetch_row($rest)) {
$driver_id = $row[0];
}
?>
I would suggest adding a new fullname field or using a temp table rather than using the concat, for performance reasons.
https://stackoverflow.com/a/29285246/3923450 should work though if you are looking for a temp solution
People enter values into a form and on one entry of the form I have multiple values.
Eg:
One Entry for Name
and Multiple entries for hobbies.
I could enter into the db by running a for loop but then that would be multiple entries for the same name for each different hobby.
How can I enter one name and all hobbies with 'space' into one DB field 'TWIG'. I could use arrays but it shows up as ARRAY but then its back to FOR loop.
for ($t=0; $t<=$_POST['tc']-1; $t++) {
echo "<BR> ts:".$_POST[$t]."<BR>";
$ths[]=$_POST[$t];
}
print_r ($ths);
$statement = $link->prepare("INSERT INTO quest(cnos, dte, twig)
VALUES(:q, :d, :t )");
$statement->execute(array(
":q" => htmlspecialchars ($_POST['iht']),
":d" => $_SERVER['REQUEST_TIME'],
":t"=> $ths
));
One possibility is to implode your hobbies / concatinate your string into one...
for ($t=0; $t<=$_POST['tc']-1; $t++) {
$ths = $_POST[$t] . " "; //Concatinate string, do no use array!
}
//Cut off last character " " to avoid ugly space at the end:
$ths = substr($ths, 0, strlen($ths) - 1);
However a more clean solution is to make a more clear database structure if you want for atomic values.
This is an 1:n relation (Each of your entries in table A relates to n instances in table B).
Here is an example that can be adapted into your schema very easy:
Table User(id[PK], name, age);
Table User_Hobbies: (user_id, hobby_descr);
--
INSERT INTO User(2, "Chris", 19);
INSERT INTO USER_User_Hobbies(2, "videogames");
INSERT INTO USER_User_Hobbies(2, "music");
--
Example query:
SELECT u.name, u.age, GROUP_CONCAT(uh.hobby_descr) AS hobbies
FROM User u
LEFT JOIN User_Hobbies uh ON u.id = uh.user_id
WHERE u.id = 123 /*Where is optional, if you want to filter for a specific user*/
GROUP BY u.id;
Possible result:
| name | age | hobbies |
chris 18 videogames, music
steve 22 computer, programming, php
Use the implode function for this as follows:
":t"=> implode(" ", $ths);
I am not sure, if I understand your question right, but if you want to insert an array as a comma-seperated string (or separated by whatever), why don't use the php implode function: http://php.net/manual/de/function.implode.php
For example:
$myHobbies = array("football", "basketball", "running");
$statement = $link->prepare("INSERT INTO quest(cnos, dte, twig)
VALUES(:q, :d, :t )");
$statement->execute(array(
":q" => htmlspecialchars ($_POST['iht']),
":d" => $_SERVER['REQUEST_TIME'],
":t"=> implode(" ", $myHobbies)
));
I think to use comma's or semicolons as separator, is better than whitespaces, since some of the hobbies could consists of two words (for example "pc gaming").
I think that better solution is to use json_encode and not implode, since it provides more robust structure.
":t" => json_encode($myHobbies)
You can use join function to store multiple value in same field in database may be it will works:-
":t"=>join(",", $ths);//if you want ,(coma) between two string
or
":t"=>join(" ", $ths);//if you want space between two string
I have this code in php:
<?php
$arstring = implode(' ',$array);
?>
the $arstring while output some values like 23, 30 etc. I have a table users(user_id, name, surname). My question is how can I get all names and surnames from users table, that have a user_id equal to those that outputs $arstring. For example how to get all names surnames from users that have user_id equal to 23, 30 etc..
The query would be something like:
$sql = 'SELECT name, surname FROM users WHERE
user_id IN (' . implode(', ', $array) . ')';
PS: if $array contains data that comes directly from the user as input and you haven't sanitized it, before running the query you should make sure that $array contains only integers (so to avoid SQL injections). You may use this code (before the query):
$array = array_map('intval', $array);
I have a string, like Elton 1999, and a MySql table with 4 fields :
table(id, name, surname, year)
I have to check if, joining these fields as "single field", it contains all the words of my string.
I mean :
1 Elton John 1999 -> must return the record
2 Elton Peter 1999 -> must return the record
3 Paris Elton 1999 -> must return the record
4 Elto John 1999 -> must not return the record
5 Elton Pierre 2000 -> must not return the record
Can I do it directly with MySql or I need first to get all the records and than parse them on server side? (on PHP, in my case)
P.S. The same result must begin if my string is 1999 Elton, so the order of my words doesnt matter...
SELECT * FROM myTbl WHERE CONCAT(name, surname, year) LIKE '%ELTON%1999'
or
SELECT * FROM myTbl WHERE CONCAT_WS(' ', name, surname, year) LIKE '%ELTON%1999'
to add a space between each of the fields. Thx majic bunnie.
Update: Well, if you want to search for possible matches on any column with a string of values in any order, then you could explode your string by space and search each word individually. See if this works
$query = "SELECT * FROM myTbl";
if(!empty($searchString)){
$query .= " WHERE ";
$arr = explode(' ', $searchString);
foreach($arr as $word)
$fields[] = "CONCAT_WS(' ', name, surname, year) LIKE %$word%";
$query .= implode(" AND ", $fields);
}
PS - I recently learned this query building technique from #yahyaE here :)
As long as your input strings are consistently formatted, you should be able to join the fields together using CONCAT_WS() with a space as the separator and compare them to your input string when querying.
I have Concatenated in mySQL to produce a field that I can search with. This contains animal as well as owner names and addresses for a client database. I need to be able to search by animal name, owner names and postcode in any order.
Thus if if my name is john smith and i own a dog called Fido and live in postcode AB1 2CD, I want the search to be yield results if any of the following are entered:
"john fido AB1"
"john AB1"
"AB1 john"
"AB1 fido"
"fido 2CD"
"2CD"
"fido"
etc... i.e any of the fields in any order, and also not complete words either so "john fido AB1" should yield the same result as "jo fi AB1"
I currently have this PHP code, taking a single text field on my search page, exploding then imploding it to add % between the search terms:
$list = explode(' ',$_GET["q"]);
$q = implode('%%', $list);
if (!$q) return;
$sql = "SELECT DISTINCT owner.AddressPrim, owner.PostcodePrim,
owner.OwnerSurnamePrim,owner.OwnerForenamesPrim,owner.OwnerID
FROM owner
Inner Join patient ON owner.OwnerID = patient.OwnerID
WHERE CONCAT_WS(' ',owner.AddressPrim, owner.PostcodePrim,
owner.OwnerForenamesPrim,owner.OwnerSurnamePrim,patient.AnimalName) LIKE '%$q%'";
This works for "AB1 john" and "john fido" but not "fido john" as it is out of order in the concatenated field.
Any help greatly appreciated
I think you're going to have to split the keywords and add a query for each keyword in the string of keywords.
So first (in PHP), split the query string and dynamically generate your SQL query, then send it to the database. Here's some pseudocode to show you what I mean:
$keywords = explode(' ', $q);
$sql = "SELECT DISTINCT owner.AddressPrim, owner.PostcodePrim,
owner.OwnerSurnamePrim,owner.OwnerForenamesPrim,
owner.OwnerID
FROM owner
Inner Join patient ON owner.OwnerID = patient.OwnerID";
$first = true;
foreach($keyword in $keywords):
if($first):
$sql += " WHERE ";
$first = false;
else:
$sql += " AND ";
$escaped = mysql_real_escape_string($keyword);
$sql += " CONCAT_WS(' ',owner.AddressPrim, owner.PostcodePrim,
owner.OwnerForenamesPrim,owner.OwnerSurnamePrim,patient.AnimalName)
LIKE '%$escaped%'";
But do beware, this is not going to be anywhere near fast for the size of tables you'll probably encounter in daily operation. You may want to look into a better way of doing fulltext search, whether it means using a library or making a cross-reference table of keywords maintained by triggers.
MySQL's fulltext search (MyISAM tables only!) could be useful to you.
http://dev.mysql.com/doc/refman/5.0/en/fulltext-search.html
You can try this http://www.sphinxsearch.com/
You need dedicated server to run this thing, but if you have one, sphinx will easily solve your problem and your queries won't load database.