get numeric values from an ENUM column's issue - mysql

to get numeric values from an ENUM column, can be using
mysql> SELECT enum_col+0 FROM tbl_name;
reference here
But in my mysql5.5 console,this query return:
1.0000000000000000000000000000000
I want to get the a integer number 1
I know I can use:
SELECT CONVERT(enum_col,UNSIGNED) FROM tbl_name;
or
SELECT CAST(enum_col AS UNSIGNED) FROM tbl_name;
I want to know why enum_col+0 return a float,
and any other way to get numeric values from an ENUM column?

Have a look at this article - Type Conversion in Expression Evaluation; it describes how MySQL does conversion between different types; there are some rules, in your case you get result as a floating-point value.
...and try another variant:
SELECT TRIM(TRAILING ')' FROM TRIM(LEADING '(' FROM TRIM(LEADING 'enum' FROM column_type))) INTO #enum
FROM information_schema.`COLUMNS` WHERE TABLE_SCHEMA = 'db_name' AND TABLE_NAME = 'tbl_name' AND COLUMN_NAME = 'enum_col';
SELECT FIND_IN_SET(CONCAT('''', enum_col, ''''), #enum) FROM tbl_name
or this one:
SELECT REPLACE(TRIM(TRAILING ')' FROM TRIM(LEADING '(' FROM TRIM(LEADING 'enum' FROM column_type))), '''', '') INTO #enum
FROM information_schema.`COLUMNS` WHERE TABLE_SCHEMA = 'db_name' AND TABLE_NAME = 'tbl_name' AND COLUMN_NAME = 'enum_col';
SELECT FIND_IN_SET(enum_col, #enum) FROM tbl_name

Related

Sql query to return column name, data type, data length, if a column is null

I have the following query:
SELECT column_name,
data_type
date_length
FROM information_schema.columns
WHERE table_schema = ’bookidz_ro_dev’
AND table_name = ’rack_level’;
And I get this error: #1054 - Unknown column '’bookidz_ro_dev’' in 'where clause'
even though the db name is correct and so is the table name.
As i tested your code is good, but those ’ quotations are not correct.
SELECT
*
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'bookidz_ro_dev'
AND TABLE_NAME = 'rack_level';
I used * because there is no Date_Length column in information_schema.columns
Looks like You are using wrong quotations, try it with correct one:
SELECT column_name,
data_type
date_length
FROM information_schema.columns
WHERE table_schema = 'bookidz_ro_dev'
AND table_name = 'rack_level';

How to select column name in select statement

I want to copy/update data from Table A to Table B. Table B has some more additional columns. I have tried the following options.
1) `REPLACE INTO `B` (SHOW FIELDS FROM 'A') SELECT * FROM `A
2) `REPLACE INTO `B`
(SELECT `COLUMN_NAME` FROM `INFORMATION_SCHEMA`.`COLUMNS`
WHERE `TABLE_SCHEMA`='test1' AND `TABLE_NAME`='A') SELECT * FROM `A
But it throws errors. Can you guys help me how to select names with select query?
UPDATE:
3) As suggested by Jerko,
I have two tables A(warehouse_id,long,lat) B(warehouse_id,long)
Applied the following statement.
SET #query = CONCAT('REPLACE INTO `A` (SELECT ',
(SELECT GROUP_CONCAT(CONCAT('`',column_name, '`'))
FROM information_schema.columns
WHERE `TABLE_SCHEMA`='test2' AND `table_name` = 'A'),
' FROM `B`)');
PREPARE stmt FROM #query;
EXECUTE stmt;
This gives me the error
"#1054 - Unknown column 'lat' in 'field list' "
You can't do this dynamically in mysql like you are trying to do. MySQL expects your list of column names to be provided directly, not from a subquery.
If you want to do this dynamically you'll have to step back upstream to whatever language you are using to interact with MySQL such as PHP or Java.
Have you tried this?
insert into B(col1, . . ., coln)
select col1, . . ., coln
from A;
That is, list the fields from A in the select clause. List the corresponding columns for B in the insert column list.
If you need the list of columns, get them from INFORMATION_SCHEMA.COLUMNS and cut-and-paste into the query.
Actually there is a way
SET #query = CONCAT('REPLACE INTO `A` (',
(SELECT GROUP_CONCAT(CONCAT('`',column_name, '`'))
FROM information_schema.columns
WHERE `TABLE_SCHEMA`='test1' AND `table_name` = 'A'
AND column_name IN (SELECT column_name FROM information_schema.columns WHERE table_schema = 'test1' AND table_name='B')) ,
') (SELECT ',
(SELECT GROUP_CONCAT(CONCAT('`',column_name, '`'))
FROM information_schema.columns
WHERE `TABLE_SCHEMA`='test1' AND `table_name` = 'A'
AND column_name IN (SELECT column_name FROM information_schema.columns WHERE table_schema = 'test1' AND table_name='B')),
' FROM `B`)');
PREPARE stmt FROM #query;
EXECUTE stmt;
Try this
INSERT INTO B (field1,field2,...,fieldN)
SELECT (field1,field2,...,fieldN) FROM A

Select column names whose entries are not null

I would like to have a list of those columns of a table that have at least one non-NULL data entries in them.
In other words, I would like to get the column names for which the following returns at least one entry:
SELECT DISTINCT column_name FROM table WHERE column_name IS NOT NULL
I tried the following:
SELECT column_name
FROM information_schema.columns
WHERE table_name = "table_name"
AND EXISTS (
SELECT DISTINCT column_name FROM table_name WHERE column_name IS NOT NULL
)
But this also returns the column names where all the entries are NULL.
So how do I get only those columns with non-NULL entries?
Create from the INFORMATION_SCHEMA.COLUMNS table a string that contains the SQL you wish to execute, then prepare a statement from that string and execute it.
The SQL we wish to build will look like:
SELECT 'column_a'
FROM table_name
WHERE `column_a` IS NOT NULL
HAVING COUNT(*)
UNION ALL
SELECT 'column_b'
FROM table_name
WHERE `column_b` IS NOT NULL
HAVING COUNT(*)
-- etc.
(One could omit the WHERE clause and substitute COUNT(*) for COUNT(column), but I think that might be less efficient on indexed columns).
This can be done using the following:
SET group_concat_max_len = 4294967295;
SELECT GROUP_CONCAT(
' SELECT ',QUOTE(COLUMN_NAME),
' FROM table_name',
' WHERE `',REPLACE(COLUMN_NAME, '`', '``'),'` IS NOT NULL',
' HAVING COUNT(*)'
SEPARATOR ' UNION ALL ')
INTO #sql
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'table_name';
PREPARE stmt FROM #sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
See it on sqlfiddle.
Use this procedure this will print columns names of a table which have atleast one not null rows.
create or replace procedure list_col_notNull(tblName in varchar2)
as
lv_col_name varchar2(200);
lv_ctr number;
lv_sql varchar2(400);
CURSOR cur_col_name is
SELECT column_name
FROM USER_TAB_COLUMNS U
WHERE table_name = tblName order by column_name asc;
begin
open cur_col_name;
LOOP
FETCH cur_col_name INTO lv_col_name;
EXIT WHEN cur_col_name%NOTFOUND;
lv_sql := 'select count(1) From ' || tblName || ' where ' || lv_col_name || ' is not null' ;
EXECUTE IMMEDIATE lv_sql into lv_ctr;
if lv_ctr > 0
then
dbms_output.put_line(lv_col_name);
end if;

mySQL to replace all strings no matter field name?

I have this query but I want to change the strings in every field_name found instead of manually changing this.
How I can do this ?
update TABLE_NAME
set FIELD_NAME = replace(FIELD_NAME, ‘find this string’, ‘replace found string with this string’);
Then you have to specify all fieldnames. Example
UPDATE tableName
SET field1 = REPLACE(field1, 'oldstring', 'newstring'),
field2 = REPLACE(field2, 'oldstring', 'newstring'),
field3 = REPLACE(field3, 'oldstring', 'newstring'),
fieldN = REPLACE(fieldN, 'oldstring', 'newstring')
You may use information_schema.columns to build a query for each column
SELECT CONCAT( 'Update table ', table_name,
' set ', column_name, ' = replace(',column_name,', \‘find this string\’, \‘replace found string with this string\’); ')
FROM information_schema.columns
WHERE table_name = '<TableName>'`
This will generate update statements for all of the columns in the table (will save you time and effort to write column names manually).

Build column definition from INFORMATION_SCHEMA COLUMNS table

I want to rename columns in database programmatically and MySQL enforces me to specify column definition in CHANGE statement.
ALTER TABLE table_name CHANGE old_name new_name column_definition
So, I want to build column definition from INFORMATION_SCHEMA.COLUMNS table. I've read answers which adjust me to parse output of SHOW CREATE TABLE table_name, but I do not want to do that in some reasons.
I want to get column definition as result of single SQL script if it is possible.
Try this:
select COLUMN_TYPE from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = '{database name}' AND TABLE_NAME = '{table name}' AND COLUMN_NAME = '{column name}';
You'll need to fill in the right values, but it should give you the precise string you'll need to fill into the ALTER statement. You will need to do some additional work to deal with default statements and NULL settings.
The complete sample:
SELECT CONCAT(
CAST(COLUMN_NAME AS CHAR),
' ',
CAST(COLUMN_TYPE AS CHAR),
IF(ISNULL(CHARACTER_SET_NAME),
'',
CONCAT(' CHARACTER SET ', CHARACTER_SET_NAME)),
IF(ISNULL(COLLATION_NAME), '', CONCAT(' COLLATE ', COLLATION_NAME)),
' ',
IF(IS_NULLABLE = 'NO', 'NOT NULL ', ''),
IF(IS_NULLABLE = 'NO' AND ISNULL(COLUMN_DEFAULT),
'',
CONCAT('DEFAULT ', QUOTE(COLUMN_DEFAULT), ' ')),
UPPER(extra))
AS column_definition
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA = 'table_schema'
AND TABLE_NAME = 'table_name'
AND COLUMN_NAME = 'column_name';
EDIT Added quoting of default value, collation and charset.