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

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

Related

SELECT * FROM MULTIPLE+DYNAMIC table_name

A Case in point is getting data from tables which is generated every day with new name like below:
select table_name from INFORMATION_SCHEMA.TABLES where table_name like 'ifhcraw%';
ifhcraw_2016_03_31_24
ifhcraw_2016_04_01_8
ifhcraw_2016_04_02_14
ifhcraw_2016_04_03_20
ifhcraw_2016_04_05_8
ifhcraw_2016_04_06_14
As you can see, there is a name convention based on rule - "ifhcraw+year+month+day+hour". But the hour of generation is not known.
Is there any way to create some SQL script which can get all data from the tables "where table_name like 'ifhcraw%'"
You can use GROUP_CONCAT to combine all the table names in a single string.
SELECT #queries := GROUP_CONCAT(CONCAT('SELECT * FROM ', table_name) SEPARATOR ' UNION ')
FROM INFORMATION_SCHEMA.TABLES
WHERE table_name LIKE 'ifhcraw%';
PREPARE stmt FROM #queries;
EXECUTE stmt;
The first query finds all the matching table names, and creates a query like SELECT * FROM <tablename>. Then it uses GROUP_CONCAT to connect them all with UNION, so the resulting query looks like:
SELECT * FROM table1
UNION
SELECT * FROM table2
UNION
SELECT * FROM table3
...
Note that by default GROUP_CONCAT is limited to returning 1024 characters. If you have lots of these tables, you'll need to increase group_concat_max_len to get everything.

Return row where any column matches input

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)

select first N columns of MySQL table

As it is possible to select top N rows from table, is there any way to select first N columns from MySQL database tables?
Thanks for your replies and maybe some parts of code in PHP.
Please have a look at Bill Karwin's answer first. But if you know how to order your column names there could be a solution that makes use of a dynamic query.
To select all column names from a table, you can use a query like this:
SELECT `column_name`
FROM `information_schema`.`columns`
WHERE `table_schema`=DATABASE()
AND `table_name`='yourtablename';
(please have a look at this answer). And making use of GROUP_CONCAT:
GROUP_CONCAT(CONCAT('`', column_name, '`') ORDER BY column_name)
we can return all column names in a single row, separated by commas:
`col1`, `col2`, `col3`, ...
(I also added quotes around the name of the column, and please notice that we have to order our list of columns somehow, otherwise there are no guarantees about the order in which column names are returned).
Then we can cut the returned string, using SUBSTRING_INDEX, in order to get, for example, the first 2 column names:
SUBSTRING_INDEX(columns, ',', 2)
and our final query, that concatenates 'SELECT ', the selected columns above, and ' FROM Tab1', and inserts the resulting string into the #sql variable is this:
SELECT
CONCAT(
'SELECT ',
SUBSTRING_INDEX(
GROUP_CONCAT(CONCAT('`', column_name, '`') ORDER BY column_name),
',',
2),
' FROM Tab1'
)
FROM
information_schema.columns
WHERE
table_schema=DATABASE()
AND table_name='Tab1'
INTO #sql;
It's value will be something like this:
#sql = "SELECT `col1`, `col2` FROM Tab1"
and you can then prepare your statement, and execute it:
PREPARE stmt FROM #sql;
EXECUTE stmt;
Please see fiddle here.
SQL requires that you name the columns you want, or else use the * wildcard.
In relational theory, there is no concept of "first N columns" because columns have no implicit order. Of course in any concrete implementation of SQL, they must have some storage order, but the SQL language doesn't have any support for fetching columns by "position" in the table, nor is there any support for fetching sequences of columns (except for *).
You cannot do this directly in MySQL, you must do this server-side. In PHP this might look like this:
<?php
$mysqli->real_query("SELECT id, title, name FROM test ORDER BY id ASC");
$res = $mysqli->use_result();
$numberOfColumnsToShow = 2;
while ($row = $res->fetch_assoc()) {
// Only select the first $numberOfColumnsToShow columns
$rowWithSpecifiedNumberOfColumns = array_slice($row, 0, $numberOfColumnsToShow);
// $rowWithSpecifiedNumberOfColumns only contains the first two columns (id, title)
}
?>

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.