Return row where any column matches input - mysql

Is it possible to create a SQL query returning a row which has any column matching input. For example:
SELECT row WHERE ANY column LIKE input
Thank you

Yes it is:
SELECT * FROM MyTable WHERE ColumnA LIKE '%input%' OR ColumnB LIKE '%input%'
If you want literally to dynamically check any column then you need to dynamically build up the list of columns and use a prepared statement.
This will use the INFORMATION_SCHEMA.COLUMNS table to find the columns in the table, then use GROUP_CONCAT() to put them into a string separated by the rest of the where clause. By itself this will give you:
ColumnA LIKE '%input%' OR ColumnB
Then you just need to CONCAT() that with the start of the statement (SELECT .. WHERE) and the LIKE for the last column. All this gets stored in a variable #sql and used as the SQL for the prepared statement:
SET #sql:=(SELECT CONCAT('SELECT * FROM MyTable WHERE ', GROUP_CONCAT(COLUMN_NAME SEPARATOR ' LIKE ''%test%'' OR '), ' LIKE ''%test%''') from INFORMATION_SCHEMA.COLUMNS where TABLE_NAME = 'MyTable');
# for debugging only
SELECT #sql;
PREPARE dynamic_statement FROM #sql;
EXECUTE dynamic_statement;
DEALLOCATE PREPARE dynamic_statement;
Here is a working SQL Fiddle to demonstrate this: http://sqlfiddle.com/#!2/f475d/22

I think you are searching for this...
SELECT * from table WHERE column a LIKE '%input%' or column b LIKE '%input%'

Use In operator. since there is no wildcards in your like operator you can try something like this.
select row from table where input in (a,b)

Related

sql : select some column which I don't know the entire name

I have a table like that :
id exemple_ABC tr_ABC exemple_BCD tr_BCD ....
I want to SELECT all of the column beginning by "exemple_"
I try :
SELECT exemple_* FROM myTable
or
SELECT exemple_% FROM myTable
But all of this doesn't work...
You cannot with standard SQL. Column names are not treated like data in SQL.
If you use a SQL engine that has, say, meta-data tables storing column names, types, etc. you may select on that table instead.
try this one
select * from information_schema.columns
where table_name='table1' and column_name like 'exemple_%'
You have to create a dynamic query thanks to the information_schema table.
SELECT
CONCAT(
'SELECT ',
SUBSTRING_INDEX(
GROUP_CONCAT(CONCAT('`', column_name, '`') ORDER BY column_name),
',',
2),
' FROM your_table'
)
FROM
information_schema.columns
WHERE
table_schema=DATABASE()
AND table_name ='your_table'
AND column_name LIKE 'your_prefix_%'
INTO #sql;
PREPARE stmt FROM #sql;
EXECUTE stmt;
Have a look here (where I have found this query I have changed a little bit): select first N columns of MySQL table
It's a pretty strange situation not knowing the exact database design, but basically your only option is to wildcard ALL columns and choosing which you want on the client side, i.e:
SELECT * FROM myTable

Search all columns of a table using a single where condition with single keyword in mysql

I have a table which consists of 64 different fields. i am going to search with a single keyword in it, Results should match the keyword from any field. Give some suggestions.
SELECT * FROM `some_table`
WHERE
CONCAT_WS('|',`column1`,`column2`,`column3`,`column4`,`column64`) # single condition, many columns
LIKE '%VT%'
Voila.
The '|' separator, by the way, is to prevent you finding coincidental matches where, e.g., column1 ends in 'V' and column2 starts with 'T', which would give you a false positive in a search for "VT".
I'm not sure if the above method is faster than the OR method (I would guess they're the same speed) , but it definitely involves less typing if you're writing the query by hand.
you can use the where with multiple condition with OR
like
where
name = 'expected'
OR rate ='expected'
OR country ='expected'
I can't see a way around your query being simple but long:
SET #term = "Somesearch";
SELECT id, title FROM sometable WHERE
col1 LIKE '%#term%' OR
col2 LIKE '%#term%' OR
col3 LIKE '%#term%' ...;
Instead of using a MySQL variable, you can just use a language-specific variable but for the sake of examples, I thought I'd stick with MySQL itself.
The "..." is where you'd place the other 61 columns/fields.
Another possibility would be to use FOR XML to get all columns to print to a single field... like this:
SELECT c.*
FROM (
SELECT a.*
,( SELECT *
FROM table_to_search b
WHERE a.KeyField = b.KeyField
FOR XML RAW) AS `Full_Text_Record`
FROM table_to_search a) c
WHERE c.`Full_Text_Record` LIKE '%Search_string%'
Might take a while to run if it is a particularly large table, but it should brute force you to find out if that string exists in any given table.
If you can translate this SQL Server syntax to MySQL
WHERE
name = #keyword OR
country = #keyword OR
department = #keyword OR
#keyword IS NULL -- match all when search text is empty
Simplest solution would be to use multiple ORs.
select * from TAB where col1 like "%VAR%" OR col2 like "%VAR%" OR......col64 like "%VAR%";
You can use like or = as per the requirement, but it will require to change your query every time you add a new column.
As an alternative, you can take SQLDump for that table and then search that file.
With some Googling,
See if this project is useful - http://code.google.com/p/anywhereindb/. Searches all the fields and praised by many.
Try to use the information from information_schema table. Look for all the columns in the table. Now, try to form your query using this information.
You could write one query that will generate a query for every column in your table.
In the example below the schema ("owner") is 'DEV_USER'
The table with your 64 fields is called 'CUSTOMER_INFO'
The criteria in the search is any column with a value of 'VT' in it:
select 'SELECT ' || COLUMN_NAME || ' FROM CUSTOMER_INFO
WHERE ' || COLUMN_NAME || q'# LIKE '%VT%';#'
FROM ALL_TAB_COLS
WHERE OWNER = 'DEV_USER'
AND TABLE_NAME = 'CUSTOMER_INFO';
This one query will generate a query for each field for you.
The results of running the above would be;
SELECT ADDRESS_1 FROM CUSTOMER_INFO
WHERE ADDRESS_1 LIKE '%VT%';
SELECT ADDRESS_2 FROM CUSTOMER_INFO
WHERE ADDRESS_2 LIKE '%VT%';
SELECT CITY FROM CUSTOMER_ADDRESSES_QASB
WHERE CITY LIKE '%VT%';
SELECT STATE_PROVINCE FROM CUSTOMER_INFO
WHERE STATE_PROVINCE LIKE '%VT%';
SELECT ZIP_POSTAL_CODE FROM CUSTOMER_INFO
WHERE ZIP_POSTAL_CODE LIKE '%VT%';
WHERE LATITUDE LIKE '%VT%';
... and so on for each column in the table
Then you just paste those queries that were generated from your first query into another tab and run them.
Hope that helps. :-)
You can use dynamic SQL to generate and execute a query that searches all the columns.
DELIMITER $$
CREATE PROCEDURE searchAllCols(inDB VARCHAR(64), inTable VARCHAR(64), search VARCHAR(32))
BEGIN
SET #matches = (
SELECT GROUP_CONCAT(CONCAT('`', COLUMN_NAME, '` LIKE "%', search, '%"') SEPARATOR ' OR ')
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = inTable and table_schema = inDB);
SET #query = CONCAT('SELECT * FROM `', inDB, '`.`', inTable, '` WHERE ', #matches);
PREPARE stmt FROM #query;
EXECUTE stmt;
END
$$
DELIMITER ;
CALL searchAllCols('table_to_search', 'searchString');

Select specific columns, along with the rest

I have a table with a lot of columns. Some of these are DATETIME, which I turn into Unix timestamps with UNIX_TIMESTAMP(). So I don't have to type out all the other columns I want from the table, is there a way of doing something like:
SELECT UNIX_TIMESTAMP(t.start) AS start,
UNIX_TIMESTAMP(t.end) AS end,
t.theOtherColumns
FROM table t
Where t.theOtherColumns is the rest of the columns in the table. To explain further; I want to select all the columns from the table, perform operations on some of them, but not type out each column name into the query.
When I do, say,
SELECT UNIX_TIMESTAMP(t.start) AS start,
UNIX_TIMESTAMP(t.end) AS end,
t.theOtherColumns
FROM table t
It selects start and end twice. I only want to return the start and end columns from UNIX_TIMESTAMP(), and exclude those columns from the t.* set.
What you can do is use this answer to help build the results you want.
A possible solution would look like
SET #sql = CONCAT('SELECT UNIX_TIMESTAMP(t.start) AS start, UNIX_TIMESTAMP(t.end) as end,', (SELECT GROUP_CONCAT(COLUMN_NAME) FROM
information_schema.columns WHERE table_schema = 'test' AND table_name =
't' AND column_name NOT IN ('start', 'end')),
' from test.t');
PREPARE stmt1 FROM #sql;
EXECUTE stmt1;
*Replace test with the name of the schema that contains your table t.
Try t.* it works under Oracle.
I don't believe there is a way to do this as you suggested, but you can do this
SELECT t.*, UNIX_TIMESTAMP(t.start) AS start, UNIX_TIMESTAMP(t.end) as end ...

MySQL wildcard in select

Is there any way to select columns with wild cards.
like
to select columns with names having type could be 'SELECT %type% from table_name' ?
Not really. You can use the * column wildcard to select all columns. If you're joining multiple tables, you can select all columns from specific table by prefixing * with the table name or alias:
SELECT a.id, a.title, b.*
FROM articles AS a
JOIN blurbs AS b ON a.id = b.article
However, you shouldn't use * unless you're writing a DB administration program.
Alternatively, you can build a statement within SQL or another language by fetching table metadata to get the column names. Using just MySQL, you can query the COLUMNS table in the INFORMATION_SCHEMA database to get the column names and use GROUP_CONCAT to build the column list for the statement.
SELECT CONCAT(
'SELECT ',
GROUP_CONCAT(COLUMN_NAME SEPARATOR ', '),
' FROM ', :db, '.', :table,
' WHERE ...'
)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA=:db AND TABLE_NAME=:table
Replace ":db", ":table" and "..." with the appropriate values. You can even turn it into a prepared statement so you can use it for any table. From there, PREPARE and EXECUTE the constructed statement.
If you're not limited to SQL for programming, it should be less messy. The DB driver for your language of choice likely offers methods to get metadata. The actual implementation would be similar to the pure SQL approach (get column names, assemble statement, prepare, execute), but shouldn't be so ugly, as you'd be using an algorithmic, rather than declarative, language.
I would be very interested in seeing the situation that this is actually required..
You can find all fields that contains type within the name using the information_schema and then using prepared statement.
set #str = (concat('select ',(select concat(group_concat(column_name),' from ',table_name)
from information_schema.columns
where table_schema = 'your_db_name' and table_name = 'your_table_name' and column_name like '%type%')));
prepare stmt from #str;
execute stmt;
deallocate prepare stmt;
Certainly possible if you are using a front-end language. If php just use
$fieldlist= "cola, colb ";
$tablename="tabl";
"select $fieldlist from $table"
My intuition is telling you are doing something simple using php-mysql but I may be wrong.

MySQL concat() to create column names to be used in a query?

I would like to concatenate column names in a way that the first part of the column name is a string and the second part is a number which is the result of another query.
For example:
SELECT CONCAT('column', mytable.mycolumn) FROM table ...
Can this be done in some way. This way it doesn't give me errors but I don't get the expected result and it seems the concatenation doesn't work.
I previously said that this couldn't be done, but I was wrong. I ended up needing something like this myself so I looked around, and discovered that server-side prepared statements let you build and execute arbitrary SQL statements from strings.
Here is an example I just did to prove the concept:
set #query := (
select concat(
"select",
group_concat(concat("\n 1 as ", column_name) separator ','),
"\nfrom dual")
from information_schema.columns
where table_name = 'columns')
;
prepare s1 from #query
;
execute s1
;
deallocate prepare s1
;
If the number of columns is fixed, then a non-dynamic approach could be:
select
case mytable.mycolumn
when 1 then column1 -- or: when 'a' then columna
when 2 then column2
when ...
else ...
end as my_semi_dynamic_column
from ...
I don't believe you can do this with CONCAT() and CONCAT_WS(). I'd recommend using the langauge you are working with the create the field names. Doing it this way would be pretty scary, depending on where the data in the database came from.
I would suggest looking at information_schema. The following code is untested but should theoretically work. Obviously replace your table name with an appropriate table name or link to information_schema.tables and use the table_type in your where clause
select concat('column', column_name) from information_schema.columns where table_name ='your table name'