Mysql like search with more than one column - mysql

I have a drupal site with the search option. If user enters the search keyword, i need to compare that with more than one columns and display the records.
I have tried the following query
$search = 'test';
$sql_query = db_select('logoinfo', 'l')->fields('l');
$or = db_or();
$or->condition('search_field', '%'.db_like($search).'%','LIKE');
$or->condition('companyname', '%'.db_like($search).'%','LIKE');
$sql_query->condition($or);
$selectlogos = $sql_query->execute();
It displays all the records matching the search keyword with the order of auto increment Id asc.
But i want to display the records first which is having both search_field and companyname matches with the keyword, after that other records which is matches with either companyname or search_field. Please advise to achieve this.

Since orderBy requires a field name and can't order by an expression, you'll need to use addExpression to get an alias and then order by that alias. The expression in my example will return 0 if the value is not in both fields and 1 if it is in both fields. As far as I know this should be standard SQL, but it may vary on different database backends; so the expression may need to be adjusted depending on the database you are using.
<?php
$search = 'test';
$sql_query = db_select('logoinfo', 'l')->fields('l');
$or = db_or();
$or->condition('search_field', '%'.db_like($search).'%','LIKE');
$or->condition('companyname', '%'.db_like($search).'%','LIKE');
$sql_query->condition($or);
$safe_search = db_like($search);
$ex_alias = $sql_query->addExpression("l.search_field LIKE '%$safe_search%' AND l.companyname LIKE '%$safe_search%'");
$sql_query->orderBy($ex_alias, 'DESC');
$selectlogos = $sql_query->execute();
?>

Related

How to count all records if use alias in select query?

I use Sphinx with Yii2 and need to query with filter by jSON field.
$query = new \yii\sphinx\Query();
$query->from('announcements');
$query->addSelect("*");
$query->addSelect(new Expression("IN(filters['color'], 'blue', 'red', 'green') AS f_color"));
$query->where("is_active = 1");
$query->andWhere("f_color = 1");
$announces = $query->all();
There is jSON field filters in my Sphinx index. For example:
[filters] => {"brand":"Toyota","model":"Prius","color":"red","price":"12000"... etc]
It works OK. But now I need to make a pagination... and there is a problem when I try to count records before $query->all()
$count = $query->count(); // Return error "no such filter attribute 'f_color'"
Generated query was:
SELECT COUNT(*) FROM announcements WHERE ( is_active = 1 ) AND ( f_color = 1 )
count() by default replaces the select part with * and this is where your alias is defined hence the error.
There are different ways to achieve it like:
use ActiveDataProvider like described here,
use META information like described here
Since you want to make a pagination I would go with the first example.

WHERE clause in MySql statement breaking page

I have selected all the appropriate columns for this statement. When I change WHERE user_id = $user, and the $user is a number, that works. However it doesn't seem to like the username letters. User is a valid column in my table and 'john' does exist. What am I doing wrong?
$user = 'john';
// Set the timestamp from the current system time
$time = time();
// Put our query together:
$query = "UPDATE table set
`time` = {$time}
WHERE user = {$user}";
In your query, here:
`user_id` = {$user},
`time` = {$time}
WHERE user = {$user}";
You're pointing twice to the same value $user, one for id, one for user, Are you sure you haven't defined that value twice in your JS scripts? Try giving different names to each value and that could help
do you miss a "," after "{$time}"?
Check the data in the user column, I have a feeling it's numeric. If you insist on using the username the look in MySQL documentation of a function to convert username to user-number and use it in your WHERE clause.

Search query to fetch data

I want write search query which fetch the data from students table based on multiple conditions like by ID , by name and by date of birth like that.
if I use OR condition like
Select * from students where Id='101' or name='Kumar' or age='21';
it will return if any one field is entered. If multiple fields are entered it will consider first only.
If I use AND condition like
Select * from students where Id='101' and name='Kumar' and age='21';
It will return only if all fields are entered. If any one of the field is empty it will return zero, I mean it will return empty. I want to get result even some fields are empty.
I'm using this quarry for swing application if I haven't enter text in one of the field then it will become empty like I'd='' not null
How to get Result at this condition
Select * from students where Id='' and name='' and age='21'
I want to get result even some fields are empty.
Then include that in your conditions. Something like this:
WHERE
(Id = '101' OR Id IS NULL) AND
(name = 'Kumar' OR name IS NULL) AND
(age = '21' OR age IS NULL)
Nesting conditions in parentheses allows you to build fairly complex conditional logic. How you define that logic for finding the records you want to find is really up to you.
Use LIKE clause without %s. So it'll be acting as a simple =. Here's how it will work.
if(txtId.getText().equals("")){
String id = "%%";
}else{
String id = txtId.getText();
}
if(txtName.getText().equals("")){
String name = "%%";
}else{
String name = txtName.getText();
}
if(txtAge.getText().equals("")){
String age = "%%";
}else{
String age = txtAge.getText();
}
resultset = statement.executeQuery("SELECT * FROM student WHERE id LIKE '"+ id +"' and name LIKE '"+ name +"' and age LIKE '"+ age +"';");
Try this out. It'll work like a charm. (It's up to you to change the query according to your database)

MYSQL ORDER BY CASE stored value

Im trying to show first the value that is stored in the 'zone' field, since each customer has different value, I want the one in his ZONE to show first in his lists. Thanks
first run a query for using the VAR later
$data = "SELECT * FROM users;
$datas = mysqli_query($con,$data) or die(mysqli_error($con));
$query = mysqli_fetch_array($datas);
Now I can use the {$query['zone']} and show those first in the query
"SELECT * FROM users WHERE ORDER by zone CASE zone WHEN '{$query['zone']}' THEN 0 ELSE 2'";
Im not getting the expected results, any advice? Thanks
I think you want something like this:
ORDER by (zone = '{$query['zone']}') desc,
zone
This assumes that the expression '{$query['zone']}' is the zone that you want to give priority to. User's whose zone's match this will appear first.

Cast function output as column name

I have come across a scenario where I need to "cast" the output of a function as the column name I want to select:
(SELECT
LOWER(DATE_FORMAT(NOW(), '%b'))
FROM lang_months
WHERE langRef = lang_statements.langRef
) AS month
Just returns the current month which is expected, but I want this to select the column called "may" in this case.
How would I do this?
Thanks, your answer gave me an idea. I just put the current date into a variable and used that in the query like so:
$thisMonth = strtolower(date('M')) ;
(SELECT
$thisMonth
FROM lang_months
WHERE langRef = lang_statements.langRef
) AS month
This is not possible. The name of an entity must be known when the query reaches MySQL.
The easiest option would probably be to determine the column name in whatever language you're using then to just use that. For example, in PHP:
$col = 'someAlias';
$query = "SELECT blah as `{$col}` FROM tbl";
I don't think this is possible.
You could create a view that offers this view on your data so you can they query it more expressively, but you're still going to have to write those 12 subqueries and aliases by hand.
This should work:
$month = LOWER(DATE_FORMAT(NOW(), '%b')); // Results in 'may'
$result = mysql_query('SELECT * FROM $month'); // Returns all records in table 'may'