I'm trying to search a whole table in mySQL for a string.
I want to search all fields and all entrees of a table, returning each full entry that contains the specified text.
I can't figure out how to search multiple fields easily; here are the details:
The table is "clients". It has about 30 fields and 800 entries, too much to show all at once in a browser. I would like to search for a name (i.e. "Mary"), but it could be in the shipping_name field or the billing_name field, or the email field, etc.
I would like to search all fields for any entries that contain the string "Mary". This is what I think should work but doesn't:
SELECT * FROM `clients` IN 'Mary'
Try something like this:
SELECT * FROM clients WHERE CONCAT(field1, '', field2, '', fieldn) LIKE "%Mary%"
You may want to see SQL docs for additional information on string operators and regular expressions.
Edit: There may be some issues with NULL fields, so just in case you may want to use IFNULL(field_i, '') instead of just field_i
Case sensitivity: You can use case insensitive collation or something like this:
... WHERE LOWER(CONCAT(...)) LIKE LOWER("%Mary%")
Just search all field: I believe there is no way to make an SQL-query that will search through all field without explicitly declaring field to search in. The reason is there is a theory of relational databases and strict rules for manipulating relational data (something like relational algebra or codd algebra; these are what SQL is from), and theory doesn't allow things such as "just search all fields". Of course actual behaviour depends on vendor's concrete realisation. But in common case it is not possible. To make sure, check SELECT operator syntax (WHERE section, to be precise).
Identify all the fields that could be related to your search and then use a query like:
SELECT * FROM clients
WHERE field1 LIKE '%Mary%'
OR field2 LIKE '%Mary%'
OR field3 LIKE '%Mary%'
OR field4 LIKE '%Mary%'
....
(do that for each field you want to check)
Using LIKE '%Mary%' instead of = 'Mary' will look for the fields that contains someCaracters + 'Mary' + someCaracters.
In addition to pattern matching with 'like' keyword. You can also perform search
by using fulltext feature as below;
SELECT * FROM clients WHERE MATCH (shipping_name, billing_name, email) AGAINST ('mary')
If you are just looking for some text and don't need a result set for programming purposes, you could install HeidiSQL for free (I'm using v9.2.0.4947).
Right click any database or table and select "Find text on server".
All the matches are shown in a separate tab for each table - very nice.
Frighteningly useful and saved me hours. Forget messing about with lengthy queries!!
A PHP Based Solution for search entire table ! Search string is $string . This is generic and will work with all the tables with any number of fields
$sql="SELECT * from client_wireless";
$sql_query=mysql_query($sql);
$logicStr="WHERE ";
$count=mysql_num_fields($sql_query);
for($i=0 ; $i < mysql_num_fields($sql_query) ; $i++){
if($i == ($count-1) )
$logicStr=$logicStr."".mysql_field_name($sql_query,$i)." LIKE '%".$string."%' ";
else
$logicStr=$logicStr."".mysql_field_name($sql_query,$i)." LIKE '%".$string."%' OR ";
}
// start the search in all the fields and when a match is found, go on printing it .
$sql="SELECT * from client_wireless ".$logicStr;
//echo $sql;
$query=mysql_query($sql);
Try this code,
SELECT
*
FROM
`customers`
WHERE
(
CONVERT
(`customer_code` USING utf8mb4) LIKE '%Mary%'
OR
CONVERT(`customer_name` USING utf8mb4) LIKE '%Mary%'
OR
CONVERT(`email_id` USING utf8mb4) LIKE '%Mary%'
OR
CONVERT(`address1` USING utf8mb4) LIKE '%Mary%'
OR
CONVERT(`report_sorting` USING utf8mb4) LIKE '%Mary%'
)
This is help to solve your problem mysql version 5.7.21
If you're using Sublime, you can easily generate hundreds or thousands of lines using Text Pastry in conjunction with multiple line selection and Emmet.
So in my case I set the document type to html, then typed div*249, hit tab and Emmet creates 249 empty divs. Then using multiple selection I typed col_id_ in each one and triggered Text Pastry to insert an incremental id number. Then with multiple selection again you can delete the div markup and replace it with the MySQL syntax.
for specific requirement the following will work for search:
select * from table_name where (column_name1='%var1%' or column_name2='var2' or column_name='%var3%') and column_name='var';
if you want to query for searching data from the database this will work perfectly.
One can take an export of the table in an excel sheet & find the string in the excel file itself.
This is not the best method and should be used with care as it can crash db with large amounts of tables and data. Somethings may need to be modified to use with your specific setup however should get you close.
<?php
class DBSearch{
// DB Connection
protected $db;
// Name of the DB to search in
protected $db_name = 'my_db_name';
// Tables to exclude from search
protected $excluded_tables = array(
'TABLE_I_DONT_WANT_INCLUDED',
);
// Search String
protected $search_string = '';
// Table has column
protected $has_column = '';
// Set the result limit per query
protected $limit = 5;
public function __construct($db_conn) {
parent::__construct();
$this->db = $db_conn;
}
public function search(string $search_str, string $has_column, array $exclude_table){
$this->search_string = $search_str;
$this->has_column = $has_column;
$this->excluded_tables = $exclude_table;
if(!empty($this->has_column)){
$table_names = $this->get_table_with_column($this->has_column,$this->excluded_tables);
}else{
$table_names = $this->get_all_tables($this->excluded_tables);
}
$query_string = $this->generate_query_string($table_names, $this->search_string);
$results = array();
foreach($query_string as $k=>$v){
$query = $v.' LIMIT '.$this->limit;
$results[] = $this->db->query($query)->result();
}
return $results;
}
/**
* Returns the column names associated with the table
* provided by the $table param
*
* #param string $table
* #return array
*/
private function get_table_column_names($table){
$response = array();
$sql = 'SELECT COLUMN_NAME, TABLE_NAME
FROM information_schema.columns
WHERE table_schema = ?
AND table_name = ?
ORDER BY table_name, ordinal_position';
$param = array($this->db_name, $table);
$result = $this->db->query($sql, $param);
if($result->num_rows() >= 1){
foreach ($result->result() as $v){
$response[$table][] = $v->COLUMN_NAME;
}
}
return $response;
}
/**
* Returns a object contaning the table names that
* have columns that have the name provided in $column
*
* You can also pass in a string or an array of tables not to in clude in
* the result set using the $exclude_table param
*
* #param string $column
* #param array|string $exclude_table
* #return object|boolean
*/
private function get_table_with_column($column, $exclude_table=NULL){
$sql = 'SELECT table_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE (COLUMN_NAME = ?
OR COLUMN_NAME LIKE ?)
AND table_schema = ? ';
if(NULL !== $exclude_table){
if(is_array($exclude_table)){
foreach($exclude_table as $v){
$sql .= ' AND TABLE_NAME != "'.strip_quotes($v).'"';
}
}
if(is_string($exclude_table)){
$sql .= ' AND TABLE_NAME != "'.strip_quotes($exclude_table).'"';
}
}
$sql .= ' GROUP BY TABLE_NAME ORDER BY TABLE_NAME ';
$query_param = array($column, '%'.$column.'%', $this->db_name);
$result = $this->db->query($sql, $query_param);
if($result->num_rows() >= 1){
return $result->result();
}
return false;
}
/**
* Returns an object contaning the table names.
*
* You can also pass in a string or an array of tables not to in clude in
* the result set using the $exclude_table param
*
* #param array|string $exclude_table
* #return object|boolean
*/
private function get_all_tables($exclude_table=NULL){
$sql = 'SELECT table_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_schema = ? ';
if(NULL !== $exclude_table){
if(is_array($exclude_table)){
foreach($exclude_table as $v){
$sql .= ' AND TABLE_NAME != "'.strip_quotes($v).'"';
}
}
if(is_string($exclude_table)){
$sql .= ' AND TABLE_NAME != "'.strip_quotes($exclude_table).'"';
}
}
$sql .= ' ORDER BY TABLE_NAME';
$query_param = array($this->db_name);
$result = $this->db->query($sql, $query_param);
if($result->num_rows() >= 1){
return $result->result();
}
return false;
}
/**
* Generates a search string for each table
* provided $table_names array
*
* #param array $table_names
* #param string $search_string
* #return array[]
*/
private function generate_query_string($table_names, $search_string){
$search_split = explode(' ', $search_string);
$search_a = isset($search_split[0]) ? $search_split[0]:'';
$search_b = isset($search_split[1]) ? $search_split[1]:'';
$queries = array();
if(is_array($table_names)){
foreach ($table_names as $v){
$query_string = 'SELECT * FROM '.$v->TABLE_NAME.' WHERE (';
foreach ($this->get_table_column_names($v->TABLE_NAME)[$v->TABLE_NAME] as $c){
$query_string .= '`'.$c.'` LIKE "%'.$search_string.'%" OR';
if(!empty($search_a)){
$query_string .= '`'.$c.'` LIKE "%'.$search_a.'%" OR';
}
if(!empty($search_b)){
$query_string .= '`'.$c.'` LIKE "%'.$search_b.'%" OR';
}
}
// Remoe Last OR
$query_string = substr($query_string, 0, strlen($query_string)-3). ')';
$queries[$v->TABLE_NAME] = $query_string;
}
}
return $queries;
}
}
// USEAGE
$search = new DBSearch($db_conn);
$exclude_table = array(
'tables',
'i_dont',
'want_searched'
);
$search->search('Something to search for', 'has_this_column', $exclude_table);
This essentials is a query builder for database tables and then runs the query on each table/column found in the DB. Maybe it will be helpful. Enjoy!
Related
Can somebody help me convert this Sql Query
SELECT *
FROM customer c
LEFT JOIN customer_order co
ON c.customer_number = co.customer_number
AND co.order_status IN ('preparing', 'prepared')
WHERE c.customer_status='unpaid'
AND c.order_status = 'unserve'
AND co.cus_ord_no IS null
into Codeigniter query just like the image below for example
When query statements do not have clauses that need to change conditionally then using $this->db-query() is the way to go.
$sql = "SELECT * FROM customer c LEFT JOIN customer_order co
ON c.customer_number=co.customer_number AND co.order_status IN ('preparing', 'prepared')
WHERE c.customer_status='unpaid' AND c.order_status='unserve' AND co.cus_ord_no IS null";
$query = $this->db->query($sql)->result();
echo json_encode($query);
It might be wise to include a check on the return from query() though because if it fails (returns false) then the call to result() will throw an exception. One way that can be handled is like this.
$query = $this->db->query($sql);
if($query !== FALSE)
{
echo json_encode($query->result());
return;
}
echo json_encode([]); // respond with an empty array
Query Builder (QB) is a nice tool, but it is often overkill. It adds a lot of overhead to create a string that literally is passed to $db->query(). If you know the string and it doesn't need to be restructured for some reason you don't need QB.
QB is most useful when you want to make changes to your query statement conditionally. Sorting might be one possible case.
if($order === 'desc'){
$this->db->order_by('somefield','DESC');
} else {
$this->db->order_by('somefield','ASC');
}
$results = $this->db
->where('other_field', "Foo")
->get('some_table')
->result();
So if the value of $order is 'desc' the query statement would be
SELECT * FROM some_table WHERE other_field = 'Foo' ORDER BY somefield 'DESC'
But if you insist on using Query Builder I believe this your answer
$query = $this->db
->join('customer_order co', "c.customer_number = co.customer_number AND co.order_status IN ('preparing', 'prepared')", 'left')
->where('c.customer_status','unpaid')
->where('c.order_status','unserve')
->where('co.cus_ord_no IS NULL')
->get('customer c');
//another variation on how to check that the query worked
$result = $query ? $query->result() : [];
echo json_encode($result);
You can do
public function view_customers()
{
$sql = "SELECT * FROM customer c LEFT JOIN customer_order co ON c.customer_number = co.customer_number AND co.order_status IN ('preparing', 'prepared') WHERE c.customer_status='unpaid' AND c.order_status = 'unserve' AND co.cus_ord_no IS null";
return $this->db->query($sql)->result();
}
You can use row() for one output to object, or row_array() if one output but array. result() is multiple objects and result_array() is multiple arrays.
My way do usually is like this:
Controller:
public function view()
{
$this->load->model('My_Model');
$data = new stdclass;
$data->user_lists = $this->my_model->view_users(array('nationality'=>'AMERICAN'));
}
Model:
public function view_users($param = null) //no value passed
{
$condition = '1';
if (!empty($param)) { //Having this will trap if you input an array or not
foreach ($param as $key=>$val) {
$condition .= " AND {$key}='{$val}'"; //Use double quote so the data $key and $val will be read.
}
}
$sql = "SELECT * FROM users WHERE {$condition}"; //Use double quote so the data $condition will be read.
// Final out is this "SELECT * FROM users WHERE 1 AND nationality='AMERICAN'";
return $this->db->query($sql)->result();
}
I am working on a query that has an optional filter, so lets assume the table name is products and the filter is the id (primary key)
If the filter is not present I would do something like this:
SELECT * FROM products;
If the filter is present I would need to do something like this:
SELECT * FROM products WHERE id = ?;
I have found some potential solutions that can mix the 2 in sql rather than doing conditions in the back-end code itself
SELECT * FROM products WHERE id = IF(? = '', id, ?);
OR
SELECT * FROM products WHERE IF(? = '',1, id = ?);
I was just wondering which one would be faster (In the case of multiple filters or a very big table) Or is there a better solution to handle this kind of situation?
A better approach is to construct the WHERE clause from the parameters available. This allows the Optimizer to do a much better job.
$wheres = array();
// Add on each filter that the user specified:
if (! empty($col)) { $s = $db->db_res->real_escape_string($col);
$wheres[] = "collection = '$s'"; }
if (! empty($theme)) { $s = $db->db_res->real_escape_string($theme);
$wheres[] = "theme = '$s'"; }
if (! empty($city)) { $s = $db->db_res->real_escape_string($city);
$wheres[] = "city = '$s'"; }
if (! empty($tripday)) { $s = $db->db_res->real_escape_string($tripday);
$wheres[] = "tripday = '$s'"; }
// Prefix with WHERE (unless nothing specified):
$where = empty($wheres) ? '' :
'WHERE ' . implode(' AND ', $wheres);
// Use the WHERE clause in the query:
$sql = "SELECT ...
$where
...";
Simplest approach is OR:
SELECT *
FROM products
WHERE (? IS NULL OR id = ?);
Please note that as you will add more and more conditions with AND, generated plan will be at least poor. There is no fit-them-all solution. If possible you should build your query using conditional logic.
More info: The “Kitchen Sink” Procedure (SQL Server - but idea is the same)
I have a string of values like :
$cat = "1,5,6,8,9";
now I would like to use that variable in WHERE clause. how do I do it ?
"select category from test where category...?"
I am using below code but I get null from number_of_result variable :
$array_of_cat = explode(",",$cat);
if($number_of_result == 0){
$mresult = mysql_query("select * from books where
GoodName like '%$title%' and GroupCode in ($array_of_cat) ");
$number_of_result = mysql_num_rows($mresult);
}
Change your SQL statement to this one. Use implode() to pass array elements in IN clause
$mresult = mysql_query("
SELECT * FROM books
WHERE GoodName LIKE '%$title%' AND GroupCode IN (" . implode(",", $array_of_cat) . ")");
You do not need to explode the variable - doing so results in an array that will result in the wrong value (the string "Array") when interpolated into the SQL string.
Despite the fact that this is unsafe (SQL injection prone) you could do:
if($number_of_result == 0){
$mresult = mysql_query("select * from books where
GoodName like '%$title%' and GroupCode in ($cat)");
$number_of_result = mysql_num_rows($mresult);
}
I strongly suggest you use the mysql_real_escape_string function to prepare your variables.
$cat = array(1,5,6,8,9);
$array_of_cat = implode(",",$cat);
if($number_of_result > 0){
$mresult = mysql_query("select * from books where
GoodName like '%$title%' and GroupCode in ($array_of_cat) ");
$number_of_result = mysql_num_rows($mresult);
}
Also, I'd strongly suggest reading up on PDO/MySQLi
What is the best way to check if a table exists in MySQL (preferably via PDO in PHP) without throwing an exception. I do not feel like parsing the results of "SHOW TABLES LIKE" et cetera. There must be some sort of boolean query?
Querying the information_schema database using prepared statement looks like the most reliable and secure solution.
$sql = "SELECT 1 FROM information_schema.tables
WHERE table_schema = database() AND table_name = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$tableName]);
$exists = (bool)$stmt->fetchColumn();
If you're using MySQL 5.0 and later, you could try:
SELECT COUNT(*)
FROM information_schema.tables
WHERE table_schema = '[database name]'
AND table_name = '[table name]';
Any results indicate the table exists.
From: http://www.electrictoolbox.com/check-if-mysql-table-exists/
Using mysqli I've created following function. Assuming you have an mysqli instance called $con.
function table_exist($con, $table){
$table = $con->real_escape_string($table);
$sql = "show tables like '".$table."'";
$res = $con->query($sql);
return ($res->num_rows > 0);
}
Hope it helps.
Warning: as sugested by #jcaron this function could be vulnerable to sqlinjection attacs, so make sure your $table var is clean or even better use parameterised queries.
This is posted simply if anyone comes looking for this question. Even though its been answered a bit. Some of the replies make it more complex than it needed to be.
For mysql* I used :
if (mysqli_num_rows(
mysqli_query(
$con,"SHOW TABLES LIKE '" . $table . "'")
) > 0
or die ("No table set")
){
In PDO I used:
if ($con->query(
"SHOW TABLES LIKE '" . $table . "'"
)->rowCount() > 0
or die("No table set")
){
With this I just push the else condition into or. And for my needs I only simply need die. Though you can set or to other things. Some might prefer the if/ else if/else. Which is then to remove or and then supply if/else if/else.
Here is the my solution that I prefer when using stored procedures. Custom mysql function for check the table exists in current database.
delimiter $$
CREATE FUNCTION TABLE_EXISTS(_table_name VARCHAR(45))
RETURNS BOOLEAN
DETERMINISTIC READS SQL DATA
BEGIN
DECLARE _exists TINYINT(1) DEFAULT 0;
SELECT COUNT(*) INTO _exists
FROM information_schema.tables
WHERE table_schema = DATABASE()
AND table_name = _table_name;
RETURN _exists;
END$$
SELECT TABLE_EXISTS('you_table_name') as _exists
As a "Show tables" might be slow on larger databases, I recommend using "DESCRIBE " and check if you get true/false as a result
$tableExists = mysqli_query("DESCRIBE `myTable`");
$q = "SHOW TABLES";
$res = mysql_query($q, $con);
if ($res)
while ( $row = mysql_fetch_array($res, MYSQL_ASSOC) )
{
foreach( $row as $key => $value )
{
if ( $value = BTABLE ) // BTABLE IS A DEFINED NAME OF TABLE
echo "exist";
else
echo "not exist";
}
}
Zend framework
public function verifyTablesExists($tablesName)
{
$db = $this->getDefaultAdapter();
$config_db = $db->getConfig();
$sql = "SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = '{$config_db['dbname']}' AND table_name = '{$tablesName}'";
$result = $db->fetchRow($sql);
return $result;
}
If the reason for wanting to do this is is conditional table creation, then 'CREATE TABLE IF NOT EXISTS' seems ideal for the job. Until I discovered this, I used the 'DESCRIBE' method above. More info here: MySQL "CREATE TABLE IF NOT EXISTS" -> Error 1050
Why you make it so hard to understand?
function table_exist($table){
$pTableExist = mysql_query("show tables like '".$table."'");
if ($rTableExist = mysql_fetch_array($pTableExist)) {
return "Yes";
}else{
return "No";
}
}
I have a PHP file which is taking in seven variables like so:
$name=$_REQUEST['membername'];
$email=$_REQUEST['email'];
$dob=$_REQUEST['dob'];
$gender=$_REQUEST['gender'];
$phone=$_REQUEST['phone'];
$county=$_REQUEST['county'];
$IP=$_REQUEST['IP'];
Some of these will not be set. What I want to do is construct a query which will search the members table such that if only $email and $dob are set it will only search by $email and $dob, ignoring the others. Or if only $phone, $name, and $gender are set, it will search those three columns only.
Is there an easier method than constructing a big block of if isset functions covering all possible permutations?
If you don't want to search on a field, pass NULL for the parameter and structure your WHERE clause something like...
WHERE
( (#parameter1 IS NULL) OR (column1 = #parameter1) )
AND
( (#parameter2 IS NULL) OR (column2 = #parameter2) )
I don't spend much time in MYSQL so the syntax is probably a bit off but you get the idea.
Presuming that you use parameters to push values into the query...
SELECT *
FROM MyTable
WHERE name = COALESCE(#p1, name)
OR email = COALESCE(#p2, email)
OR dob = COALESCE(#p3, dob)
...
...
If you construct a query string in PHP you can, instead, take another tack:
function AddWhere(&$where, $dbFieldName, $fieldValue)
{
if ($fieldValue <> "")
{
if (strlen($fieldName) > 0)
$fieldName .= " AND ";
$fieldname .= '(' + $dbFieldName + ' = \'' + $fieldValue + '\')'
}
}
Then, when you're retrived the variables, build a SQL statement thusly
$whereClause = ''
AddWhere($whereClause, 'name', $name)
AddWhere($whereClause, 'email', $email)
AddWhere($whereClause, 'dob', $dob)
...
IF (strlen($whereClause) > 0)
{
$sql = 'SELECT * FROM MyTable WHERE ' + $whereClause
... etc
}
(I'm not great at PHP, so the syntax may be somewhat screwed up).