I have a table name 'user' for example. I have field 'name' and field 'family' in this table.
I use jQueryUI auto-complete for top search in my site for search people just like Facebook.
Example of jQueryUI I use (half code):
$( "#mainsearch" ).bind( "keydown", function( event ) {
if ( event.keyCode === $.ui.keyCode.TAB &&
$( this ).data( "ui-autocomplete" ).menu.active ) {
event.preventDefault();
}
})
And I have PHP files get search result code like this:
$name = $_GET['term'];
$results = array();
$s = qselectall("select * from user where(name LIKE '%$name%' or family LIKE '%$name%' ) limit 15",$db);
while($f = mysqli_fetch_array($s,MYSQLI_ASSOC)){
if($userid != $f['id']){
$name = $f['name'].' '.$f['family'];
$url = $siteurl.$f['username'].'/';
array_push($results, array('id' => $f['id'],'value' => $name,'url' => $url));
}
}
echo json_encode($results);
But it has 1 problem.
User's cannot search with name and family.
They must insert name OR family just in input box for it to work.
Is there any SQL code for search LIKE where( name and family = $text) ?
EXAMPLE:
We have someone with name 'alex' and with last name 'alexian'.
So user search for 'alex alexian' but they get no results why?
Because not name and not family in table = 'alex alexian'.
So they must search 'alex' or 'alexian' for it to work.
Try this:
SELECT * FROM user
WHERE concat_ws(' ',name,family)
LIKE '%$name%';
The concat_ws function concatenates multiple columns 'with separator' (_ws). In this case, the separator is a space (' '). See the MySQL documentation for further information.
Demo: http://www.sqlfiddle.com/#!2/aac0f/8
Related
Create a new post and publish it.
The title is my test for search, content in it is as below:
no host route
Check what happen in wordpress database.
select post_title from wp_posts
where post_content like "%no%"
and post_content like "%route%"
and post_content like "%to%"
and post_content like "%host%";
The post named my test for search will not be in the select's result.
Type no route to host in wordpress search bar,and click enter.
The post named my test for search shown as result.
I found the reason that the webpage contain to ,in the left upper side corner ,there is a word Customize which contains the searched word to.
How to change such search action in wordpress serach bar?
I want to make the search behavior in wordpress saerch bar, for example ,when you type no route to host, equal to the following sql command.
select post_title from wp_posts where post_content like "%no%route%to%host%";
All the plugins in my wordpress.
CodePen Embedded Pens Shortcode
Crayon Syntax Highlighter
Disable Google Fonts
Quotmarks Replacer
SyntaxHighlighter Evolved
There's this addition to the SQL WHERE clause on wp-includes/class-wp-query.php:1306:
<?php
// wp-includes/class-wp-query.php:~1306
foreach ( $q['search_terms'] as $term ) {
//...
$like = $n . $wpdb->esc_like( $term ) . $n;
$search .= $wpdb->prepare( "{$searchand}(({$wpdb->posts}.post_title $like_op %s) $andor_op ({$wpdb->posts}.post_excerpt $like_op %s) $andor_op ({$wpdb->posts}.post_content $like_op %s))", $like, $like, $like );
// ...
Therefore, I'd hook into the pre_get_posts, and supply the words of the query as explicit "search_terms", since they get added into that clause, with the LIKE modifier just as you said were looking for!
So, we might do something like this:
<?php
// functions.php
function fuzzify_query(\WP_Query $q) {
if (true === $q->is_search()
&& true === property_exists($q, 'query')
&& true === key_exists('s', $q->query)
) {
$original_query = $q->query['s'];
$words = explode(' ', $original_query);
$fuzzy_words = array_map(
function($word) {
return '%'.$word.'%';
},
$words
);
$q->query_vars['search_terms'] = $fuzzy_words;
return $q;
}
return $q;
}
add_action('pre_get_posts', 'fuzzify_query', 100); // Or whatever priority your fuzziness requires!
I've had a look around Stackoverflow and can't seem to find what I am looking for.
I have a dynamically updating AJAX search form which shows location data from database.
The issue I am having is with this query here:
$sql = "SELECT location FROM location_data WHERE location LIKE ? LIMIT 10";
Let me explain what is happening first. There are 3 different columns in a database table, one called location, one called CRS and one called tiploc.
I would like to display results like the following:
Select location FROM location_data WHERE location(textbox) is LIKE ?(what the person typed in) OR CRS is LIKE ? or TIPLOC is LIKE ?
Now i've only tried it with CRS so far, and ive done the following query:
$sql = "SELECT location FROM location_data WHERE location OR CRS LIKE ? LIMIT 10";
The above only displays the CRS result (exact match) and doesn't provide any suggestions for location, only shows CRS. Does anyone know how I can amend my query, so that it searches both location and CRS and TIPLOC, LIKE on location, but exact match only on CRS and TIPLOC?
if(isset($_REQUEST['term'])){
// Prepare a select statement
$sql = "SELECT location FROM location_data WHERE location LIKE ? LIMIT 10";
if($stmt = mysqli_prepare($link, $sql)){
// Bind variables to the prepared statement as parameters
mysqli_stmt_bind_param($stmt, "s", $param_term);
// Set parameters
$param_term = $_REQUEST['term'] . '%';
// Attempt to execute the prepared statement
if(mysqli_stmt_execute($stmt)){
$result = mysqli_stmt_get_result($stmt);
// Check number of rows in the result set
if(mysqli_num_rows($result) > 0){
// Fetch result rows as an associative array
while($row = mysqli_fetch_array($result, MYSQLI_ASSOC)){
echo "<p>" . $row["location"] . "</p>";
}
} else{
echo "<p>No matches found</p>";
}
} else{
echo "ERROR: Could not able to execute $sql. " . mysqli_error($link);
}
}
// Close statement
mysqli_stmt_close($stmt);
}
// close connection
mysqli_close($link);
Now heres the on page search, the field I am pulling input from is called "location".
--Code for JS AJAX Search--
<script type="text/javascript">
$(document).ready(function(){
$('.search-box input[type="text"]').on("keyup input", function(){
/* Get input value on change */
$(".result").show();
var inputVal = $(this).val();
var resultDropdown = $(this).siblings(".result");
if(inputVal.length >2){
$.get("backend-search.php", {term: inputVal}).done(function(data){
// Display the returned data in browser
resultDropdown.html(data);
});
} else{
resultDropdown.empty();
}
});
// Set search input value on click of result item
$(document).on("click", ".result p", function(){
$(this).parents(".search-box").find('input[type="text"]').val($(this).text());
$(this).parent(".result").empty();
});
});
$(document).click(function(){
$(".result").hide();
});
</script>
You need to repeat the LIKE expression for each column.
$sql = "SELECT location
FROM location_data
WHERE location LIKE ? OR CRS LIKE ? OR TIPLOC LIKE ?
LIMIT 10";
And since there are now 3 placeholders in the query, you need to fill them all in with the binding:
mysqli_stmt_bind_param($stmt, "sss", $param_term, $param_term, $param_term);
For every individual expression in OR, you have to specify their comparison conditions. Note the location LIKE ? instead of LOCATION OR:
$sql = "SELECT location
FROM location_data
WHERE location LIKE ?
OR CRS LIKE ?
OR TIPLOC LIKE ?
LIMIT 10";
Note: LIMIT clause without ORDER BY is non-deterministic in nature, since MySQL stores an unordered dataset. It basically means that, any 10 rows can be returned by MySQL (if not using ORDER BY).
I have a calendar (FullCalendar) where the user can filter down results based on a few params (Tutor Secondary Tutor, Lesson, Location). When the user makes a change to the query it hits the following code.
The issue I am having is the 'OR'. What I really want is an IF input is null then get all.
If User { Get all lessons where lead_tutor_id = 1 and secondary_tutors_id = 1 }
If User and Location { Get lessons where the user is as above, but have location_id = 3 }
etc, etc.
So, is there a way I can fall back to get ALL the results IF only one or two filters are set?
$current_events = Calendar::Where(function($query) use ($start_time, $end_time, $tutor, $location, $lesson)
{
$query->whereBetween('date_from', [$start_time, $end_time])->orderBy('date_from')
->whereRaw('lead_tutor_id = ?
OR secondary_tutors_id = ?
OR location_id = ?
OR lesson_id = ?',
[
$tutor, // Input get() for user
$tutor, // Input get() for user
$location, // Input get() for location
$lesson, // Input get() for lesson
]
);
})->with('lessons', 'leadtutor', 'secondarytutor')->get();
I've been playing with Query Scopes, but this seems to fail if passing a NULL value through to it.
Any help is very much appreciated. Thanks in advance.
You can build the query on forehand, store it in a variable and use it once its build.
$query = isset($var) ? $var : '';
$query .= isset($othervar) ? $othervar : '';
whereBetween(*)->orderBy(*)->whereRaw($query)
Only thing you need to keep in mind is to insert the 'OR's in the right place . So have like a check for wether it is the first thing to be inserted or not, if not then put 'OR' in front of it.
Hope that is enough info to help you.
After the advice from Saint Genius, I have got this working:
$built_query = [];
isset($lead_tutor) ? $built_query['lead_tutor'] = 'lead_tutor_id = ' . $lead_tutor . ' ' : null;
isset($secondary_tutor) ? $built_query['secondary_tutor'] = 'secondary_tutors_id = ' . $secondary_tutor . ' ' : null;
isset($location_id) ? $built_query['location'] = 'location_id = ' . $location_id : null;
isset($lesson_id) ? $built_query['lesson'] = 'lesson_id = ' . $lesson_id : null;
// Flatten the array so we can create a query and add the word ADD in between each element.
$built_query = implode(" AND ", $built_query);
// Run the query
$current_events = Calendar::whereBetween('date_from', [$start_time, $end_time])->orderBy('date_from')->whereRaw($built_query)->with('lessons', 'leadtutor', 'secondarytutor')->get();
Are there pre-existing libraries that will take a user input and transform it into a SQL WHERE clause?
For example given a database that has columns first_name, last_name, and address the user could input something like:
John State St
and the library would build a query such that it would return rows that match a guy named John that lived on State St (or a guy named State that lived on John St, for that matter).
It could also support things like specifying the column:
first_name:John address:State
I have some simple code to handle some of these cases already but it's getting a little unwieldily. I would think there are some pre-existing solutions to this problem but I'm having a hard time finding them. Generally, the problem is how to enable the user to easily search a structured database with a single input field.
In this matter you can break down string as multiple values using string manipulation, and then search for each word in each column using "or" conditions.
additionally you can define index on columns so as to achieve faster search.
You might have tried this technique since you mentioned, but you have to look up each word in each column
Jquery UI autocomplete could be what you are looking for. the css along with it is also necessary please see this link http://api.jqueryui.com/autocomplete/ for the .js ans css needed.
$( "#myInputBoxId" ).autocomplete({
source: "search.php",
minLength: 2,
select: function( event, ui ) {
log( ui.item ?
"Selected: " + ui.item.value + " aka " + ui.item.id :
"Nothing selected, input was " + this.value );
}
});
and in search.php
<?php
include 'config.php';
$results =array();
$req = "SELECT product_name "
."FROM table4 "
."WHERE product_name LIKE '%".$_REQUEST['term']."%' LIMIT 5";
$query = mysqli_query($con,$req);
while($row = mysqli_fetch_array($query))
{
array_push($results,$row['product_name']);
}
echo json_encode($results);
}
I am creating nodes pro-grammatically by fetching emails. Where I am splitting the subject of the mail for creating it for specific group & the title of the node.
Now I want to fetch the group_id by the description of the group and wrote query for it, but it's not working. Let me paste the code here..
list($group_name, $title_text) = explode(', ', $title);
$query = "SELECT * FROM {og} WHERE og_description = ' ".$group_name." ' ";
$group_details = db_query($query);
while ($group = db_fetch_object($group_details)) {
$gid = $group->nid;
}
echo $gid;
echo $gid is giving nothing. Though $group_name = 'Logo design' & gid = 1442 for it in table.
Is there anything I am missing here ?
Check out the following two pages , the examples give here does not use the single quotes around the placeholder in the query ($group_name - in your example) .
http://drupal.org/node/310072
One of the lines says "Note that placeholders should not be escaped or quoted regardless of their type" .
http://drupal.org/node/1407528
I have solved it. Here is the answer:-
$title = "ED's presentation, This content is for ed's presenation"; //This is the subject of the mail, which I am fetching.
list($group_name, $title_text) = explode(', ', $title);
$query = "SELECT nid FROM {og} WHERE og_description = '".$group_name."'";
$group_details = db_query($query);
while ($group = db_fetch_object($group_details)) {
{
$gid = $group->nid;
}
Thanks :)