I have a database with a table that contains names, some examples in the column of name:
"John Doe"
"Kevin De Bruyne"
So you'll notice that a name contains multiple words.
I also got a spreadsheet with a list of names, this is there structure:
"DOE John"
"DE BRUYNE Kevin"
(last names in caps and in front of first name)
My question is how i can write a query that checks if the name in my spreadsheet is already in the database.
I tried it with some basic queries but i couldn't figure it out so i think i'll need regular expressions to split the words? How can I do this?
This is what i have to split the words, how can i build the query? Thank you!
(\b[^\s]+\b) (splits "My name is Onovar" into "My","name","is" and "Onovar")
*Database structure:
Database name: mydb
table: people
column: name
So i need something like: If 'name from spreadsheet' does not exist in table people, insert 'name of spreadsheat' into table people*
You can do it like this.
$array = explode(" ", $string);
$names = implode(",", $array);
$query = "SELECT * FROM persons WHERE id IN ($names)";
then you run the query using PDO or mysqli.
EDIT
missread the question. Above solution uses php
What you realy need is all names in a comma seperated list, then you could use this query
"SELECT * FROM persons WHERE id IN ($names)"
where $name would be your comma separated list.
Ok, I found it.
So i put my data from my excel in an array.
$array = ["name1 firstname1","name2 firstname2",...];
i go trough every element, split the words (space)
foreach ($array as $element){
$subex = explode(' ', $element);
then I copy the last element to the front
array_unshift($subex , end($subex));
and delete the last part so i have this array: "firstname,name"
array_pop($subex);
next, i break the array so i get a string like this: "firstname name"
$naam = implode(' ', $subex);
after that i make everything lowercase
$low = strtolower($naam);
except the first letters of each words, they have to be caps
$up = ucwords($low);
after that i create my myqsl query that skips doubles and adds new ones
echo 'INSERT IGNORE INTO politici
SET naam = "'.$up.'",
partij_id = 23;';
echo '<br />';
}
And i had to be sure that every name column is unique.
Related
i have question i don't know better approach to do it in mysql. I have a table in mysql with list of regex's each regex represent a company order number
i want to be able to compare a number to that list to get which company this number belongs to. the lazy way is to list all the regex in php and then using loop to get the company , but i want to do this using the power of mysql .
Like #Mech mention this might be vague.
i will try to explain it more :
I have two tables table with actual regex pattern in plain text in a column like "^[8]{1}[0-9]{10}$"
and this pattern belong to a company , there is more than 500 regex patterns .
Thank you.
Here you go #BM2ilabs. A function as requested :)
carrierID(88888141234);
function carrierID($ordernum) {
// create a connection to your db here
// fetch data needed for loop
$sql = "SELECT regex, carrier_id FROM `company_tbl_from_image`";
// fetch results
$results = $conn->query($sql);
// loop through $results
foreach ($results as $result) {
// individually check against each regex in the table
$regex = $result[regex];
// find first instance of $regex, where the $ordernum is unique, there should only be one match
if (preg_match('/'.$regex.'/', $ordernum)) {
$carrier_id = $result[carrier_id];
break; // remove break to show other matches
}
}
// check if $carrier_id is empty
if ($carrier_id <> "") {
echo $carrier_id;
} else {
echo "No carrier ID found.";
}
}
MySQL only option. Just search this:
SELECT carrier_id FROM `company_tbl_from_image` WHERE 'order number' REGEXP regex
I have this query:
$sql = "
INSERT INTO table SET
name = '$name',
sku = '$number',
description = '$desc'
";
But the rows containing some special characters (in my case this ') are not inserted.. How I can solve?
Thanks in advance.
When you construct your query, you need to escape the data you are inserting.
You need to at least use addslashes() function in PHP, like this:
$sql = "INSERT INTO table SET name = '".addslashes($name)."', sku = '".addslashes($number)."', description = '".addslashes($desc)."'";
However more correct way is to use a different function than addslashes, which would properly handle all characters in the data, not only apostrophes.
I am using my custom 'escape' function like this:
function escape($text)
{
return str_replace(array('\\', "\0", "\n", "\r", "'", '"', "\x1a"), array('\\\\', '\\0', '\\n', '\\r', "\\'", '\\"', '\\Z'), $text);
}
So using this function, you would write:
$sql = "INSERT INTO table SET name = '".escape($name)."', sku = '".escape($number)."', description = '".escape($desc)."'";
You must use parameterised queries instead of manually appending those values. Currently if name, number or description would contain any sql it would get executed.
A lot more detailed answer is in How can I prevent SQL injection in PHP?
Read about escaping characters in mysql. I think it is done with \
I need to insert ~150 simple rows (an id, and a static status of 'discard'). I have a string of the ids:
'123', '234r', '345', '456xyz'...
What's the simplest way to insert rows using this string of ids?
It seems like maybe there's some way to split the string on commas and... create a temp table to ...? I don't know - it just seems like this is the kind of thing that MySQL often manages to pull off in some cool, expedient way.
An example how to do create an INSERT statement with a few lines of PHP:
<?php
// copy your string of ids into this variable
$input = "'123', '234r', '345', '456xyz'";
// modify next line to get your desired filename
$filename = 'insert.sql'
// modify next line to your table name
$insert_statement = "INSERT INTO your_table_name (id, status) VALUES \n" .
'(' . implode(", 'discard')\n(", explode(', ', $input)) . ", 'discard');\n";
file_put_contents($filename, $insert_statement);
?>
Note
This is for this special use case. If the string of ids contains some special characters like single quotes, then this simple approach will fail.
The one way is to create CSV file with appropriate records and upload it at once to mysql.
Please follow this tutorial: http://www.mysqltutorial.org/import-csv-file-mysql-table/
Got a question for you all...
What would be the best way to search my table by array, that has an array in the table.
EG:
$var = (1,4,7,9,14)
$Query = "SELECT * FROM business_listings WHERE category IN ($var)";
'category' would have 4,27,89,101
How can I get this to match if one of the numbers in the $var matches one of the numbers in the table.
If your database column is a list of comma separated values, and you're searching for one value in that list, then you're in a different situation.
If your category column contains the text value 410,406,149,152, like you commented below, and you're searching for fields whose category contains 152, then you'll need to use MySQL's FIND_IN_SET() function.
If you have to check multiple values, then you need to use more than one FIND_IN_SET. If you read the documentation, you'll see that the first argument for FIND_IN_SET must be a single string, not a string list (it can't contain a comma). Use the following instead:
$var = "401,320,152";
$items = explode(",", $var);
foreach ($items as &$i) {
$i = "FIND_IN_SET('" . $i . "', `category`)";
}
$search = implode(" OR ", $items);
unset($i);
$query = "SELECT * FROM business_listings WHERE " . $items;
This will output:
SELECT * FROM business_listings WHERE
FIND_IN_SET('401', `category`) OR
FIND_IN_SET('320', `category`) OR
FIND_IN_SET('152', `category`)
The above script will work even if $var contains only one value.
Finally, as tadman mentioned, since we're getting into queries that can be tricky to build with prepared statements, you need to make sure you're escaping and sanitizing your input properly. For an example, if $var is being retrieved from the user somehow, then before you modify it in any way, you need to escape it with mysqli_real_escape_string():
$var = $mysqli->real_escape_string($var);
Assuming that $mysqli is your open MySQLi connection.
Hope this helps!
User Form Input - City
User Form Input - Venue
User Form Input - Cover
User Form Input - Time
User Form Input - Date
User Form Input - Number1
User Form Input - Number2
(if any are blank they are coverted to '*' on the way in. But could be whatever works.)
my $grabgig = $hookup->prepare(qq{SELECT `VenueNumber`,`Venue`,`CoverCharge`,`SetLength`,`City`,`Owner`,`Date`,`Time`,`Image1`,`Number`
FROM `gigs`
WHERE VenueNumber > ? AND `City` = ? AND `Venue` = ? AND `CoverCharge` = ?
AND Date = ? AND `Number` > ? AND `Number` < ?
AND `Time` LIKE ? LIMIT ?,?});
##########################################
$grabgig->execute('100',$city,$venue,$cover,'*',$number1,$number2,?,'0','6')
or die "Did not execute";
That is a basic example above.
I want to be able to return results based on the City Input.
If more input is present, then narrow down results accordingly.
But the query returns nothing if fields are empty (*).
I tried wildcards and so on then, I experimented with LIKE and NOT LIKE.
This seemingly simple search is driving me nuts.
Can someone help this newbie?
OK, I'm pretty unsure what you mean, BUT, my best undererstanding of what you're trying to do is to query like you do now BUT if a particular field is not populated in the form, to avoid adding that field to the where clause; as opposed to current query which instead does and myField="*".
Correct?
If that's so, you need to build your query, and replacement list, in pieces:
my $sql = qq{SELECT MY_FIELD_LIST_TOO_LAZY_TO_TYPE FROM `gigs` WHERE 2=2};
my #replacement_values = (); # These go into execute() instead of "?"s
if ($city ne "*") {
$sql .= qq[AND city = ?];
push #replacement_values, $city;
}
if ($number1 ne "*") {
$sql .= qq[AND number > ?];
push #replacement_values, $number1;
}
# ... more values processed the same way
my $grabgig = $hookup->prepare($sql);
$grabgig->execute(#replacement_values) or die "Did not execute";
If you want to do it more intelligently (i.e. to generalize), you will have the form fields in a hash; have a config hash mapping the form field name to the DB column name and the operator, and instead do the above as:
my %fields = (
city => ["city" , "="]
,number1 => ["number", ">"]
,number2 => ["number", "<"]
);
my $sql = qq{SELECT MY_FIELD_LIST_TOO_LAZY_TO_TYPE FROM `gigs` WHERE 2=2};
my #replacement_values = (); # These go into execute() instead of "?"s
foreach my $field (keys %form_data) {
next unless exists $fields{$field};
if ($form_data{$field} ne "*") {
$sql .= qq[ AND $fields{$field}->[0] $fields{$field}->[1] ?];
push #replacement_values, $form_data{$field};
}
}
my $grabgig = $hookup->prepare($sql);
$grabgig->execute(#replacement_values) or die "Did not execute";
I am assuming that you want to construct a query where only a few input parameters have valid values and the rest are undefined. If that is indeed what you want, here is what you could do: Construct the query dynamically. Here are the steps you could take assuming you are using CGI.pm and assuming that the where clause is just a series of "this = that" - In your case you have different operators - but the idea is the same.
First construct a "where" string from the CGI query parameter (Sorry untested code):
my $qrystr = '';
foreach ($query->param) {
if (my $val = $query->param($_)) {
$qrystr .= "where $_ = " . $dbh->quote($val) . ' and ';
}
}
$qrystr .= "where 1 = 1";
Now you can just prepare and execute the query : "select * from table $qrystr"
If you want automatic quoting you will have to use bind parameters which is an easy extension of the code above
Update There was a missing "where" in the last true clause "1 = 1" - Sorry, added it now
Sorry, the formatting bar was not appearing so, I rebooted. Now I cannot edit my question or comment.
What I am trying to do is provide a search for the users.
They select a city from a dropdown then some optional data can be entered / selected to narrow the results.
The optional data May or May Not be present in the table, could be a blank field.
I would like the results to show based on the selected criteria of the search in that City.
So, WHERE selected "input city" = "tables city column" look for the other options (ignore that particular criteria if field is empty) and return any matches that exist for that city.
I am then pushing into array in a While for output display.
I guess it would be like a car query. Select make where doors = 2 and color = red and engine = hamsterwheel but, the color field may be empty in the database..