SQL: Remove spaces in all tables - mysql

I want to remove all spaces in front and after the entries in all my columns in all my tables. For one column I use UPDATE table_name SET column_name= LTRIM(RTRIM(column_name)) which works well. However, I would have to copy and paste all the names in order to do this for all columns and tables.
Is there a simpler way, e.g. by looping trough somehow? A loop for one table would be very useful already!
Cheers!

You can create a dynamic query wich will loop against INFORMATION_SCHEMA.COLUMNS table and construct your final string wich will updates all the columns.
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'table_name';
will gives you the name of all columns. Then you can filter on column type or whatever you want.

Related

Eliminate underscores and convert to lowercase MySQLselect query column names

I am stuck at what seemed to be a very simple task in MySQL.
I have a table A with fields A_Id and A_Name.
MySQL query - SELECT * FROM A;
Obviously, in the output, the column names are A_Id and A_Name. But I want them to be aid and aname, that is, eliminating all underscores and converting to lowercase only the column names.
I think this should be possible. Any help/suggestion is appreciated.
EDIT:
Why do I need to do this?
I have indexed all these fields in ElasticSearch, and then querying using Spring Data Elastic, using named queries becomes difficult when there are underscores in the field names
I did look around for some answers, but all of them are either ALTER statements or manipulating the field values using REPLACE, none of which suit my usecase.
Thanks :)
You need to use the AS keyword to change the column names in the output:
SELECT A_Id as aid, A_Name as aname
FROM A;
There's no simple way to do this automatically for all columns, you need to list each column specifically. The only way to automate it would be to write a stored procedure that created the query dynamically by querying INFORMATION_SCHEMA.COLUMNS.
The query to get the columns would include something like:
SELECT GROUP_CONCAT(CONCAT(column_name), ' AS ', REPLACE(LOWER(column_name), '_', '')) AS select_list
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_name = 'A';

how to create a new table from `describe` statement in sql?

I want to create a new table with rows of the column names. Essentially, I want to put the output of a decribe statement into a new table, so that I can use a where clause to only extract certain column names. I'm using sparksql.
How do I do this? Thanks.
No need to create an additional table just use either SHOW COLUMNS command instead of describe with filter, or query information_schema.columns table with a select.

Replace column names, table names and other structures using a query

I want to search the structure of my MySQL db and replace structures that contain or equal "xyz*"... column names and table names are the main thing, but I'd like to search all structures.
Then, I want to replace "xyz*" with "abcdefg".
I doubt one can do this with one query. What you can do is create ALTER statements. I would write a small program (in the language of your choice) and
first I would get the table names like this:
select table_name from information_schema.tables;
The result set has to be checked in a loop, if there is a table named "xyz*" then create an ALTER statement:
RENAME TABLE tbl_name TO new_tbl_name
For the colums, you would have to get each Table again, then all colums for each table:
SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'tbl_name';
the again a loop to change the columns name, this time using ALTER TABLE.
see also:
https://dev.mysql.com/doc/refman/5.1/en/alter-table.html
https://dev.mysql.com/doc/refman/5.0/en/rename-table.html

How can I delete duplicate rows from a table without naming columns in the query?

I am tracking history of changes to rows in a table that is filled with a trigger on update of another table. It tracks the revision history of the main table.
Often, my users, out of habit, will hit the SAVE button even though they have not changed anything in the record, and the system will still record a copy of that row as a revision in the history table, despite the fact that nothing has changed.
Lets say I have the tables with columns like this (although mine have about 40+ cols):
Main Data:
id, name, phone, task, dob, timestamp, note, drivername, student, doctor, userid
On Update of Main Data, insert into history:
revisionid, revisiontime, id, name, phone, task, dob, timestamp, note, drivername, student, doctor, userid
The solutions to find duplicate records presented in this site and on other sites all will work well, if I wanted to list out the columns by hand.
The problem is that there are many many columns, and that I often add columns and don't want to rewrite this query every time.
When the user saves, often only the timestamp will change. What I want to do is keep only the revisions where values have changed (ignoring the revisionid and revisiontime which always change).
In the query, I dont want to list any other column names besides the columns which i want to ignore. Is it possible?
Pseudo code:
DELETE [rows, except one] FROM historytable WHERE [all columns match values] EXCEPT [these few columns which can still be different and be deleted]
Here are a few reference questions:
Deleting duplicate rows from a table
How to check for duplicates in mysql table over multiple columns
MySQL remove duplicates from big database quick
No, it isn't possible to delete duplicates from a table without specifying the columns.
The only way I know of to use a SQL statement to trim a table of dups without specifying an explicit column list is to do the following. Create a new copy with only distinct records:
create table T_UNIQUES as select distinct * from T;
You'd have to create a new table, rename the old one and then rename the new one into place. This is sometimes done on data warehouses when a DELETE operation is too slow. However, this doesn't ignore any timestamp columns, so it may not be adequate.
The only way I know to write a prune your history table with something automatic and extensible is to extract the columns from the data dictionary (INFORMATION_SCHEMA). This only automates it, but doesn't avoid specifying the columns in question.
My approach would be to fix the trigger. It sounds broken / inadequate; I would rewrite it to do an "UPSERT" instead of a blind INSERT.
My thought process is as following..
List all the column names (with an exclusion list)
SELECT COLUMN_NAME
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_SCHEMA='db'
AND TABLE_NAME='table'
AND COLUMN_NAME NOT IN ('columnToIgnore')
Store the names as rows in a temporary table
CREATE TEMPORARY TABLE IF NOT EXISTS columnNames AS (step1);
Fetch all records from temporary table 'columnNames' and store in a variable.
SELECT GROUP_CONCAT(COLUMN_NAME) into #cols FROM columnNames;
Prepare the final statement, list all the redundant rows. (I used SELECT for checking)
SET #sql = CONCAT('SELECT CONCAT_WS(" ",',#cols,') AS allColumns FROM targetTable GROUP BY allcolumns');
To sum up,
CREATE TEMPORARY TABLE IF NOT EXISTS columnNames AS (SELECT `COLUMN_NAME`
FROM `INFORMATION_SCHEMA`.`COLUMNS`
WHERE `TABLE_SCHEMA`='dbName'
AND `TABLE_NAME`='tableName'
AND `COLUMN_NAME` NOT IN ('columnNameToIgnore'));
SELECT GROUP_CONCAT(COLUMN_NAME) into #cols FROM columnNames;
SET #sql = CONCAT('SELECT CONCAT_WS(" ",',#cols,') AS allColumns FROM targetTable GROUP BY allcolumns');
PREPARE stmt FROM #sql;
EXECUTE stmt;
Who says we can't use chainsaw to slice a bread ;)

MySQL : multiple column values as 1 comma-separated string?

Suppose I have a select query like :
SELECT * FROM tablename
and in the table are columns : field1, field2 and field3
Does anyone know if it's possible to get a resultset with only 1 row with 1 field, with comma separated values of the columns, like this :
"fieldvalue1, fieldvalue2, fieldvalue3"
Problem is that I don't know the column names of the table in advance...
Another problem is that a prepared statement is not the way to go, since all this should be done from within a trigger, and MySQL doesn't allow dynamic cursors/selects inside a trigger.
I have done some research and only came as far as GROUP_CONCATenating the column names correctly. But the problem is, that
SELECT (SELECT GROUP_CONCAT( cols.column_name) FROM (SELECT column_name FROM information_schema.columns WHERE table_name='test_table') as cols) FROM test_table
will return one and the same concatenated string containing the column names, once for each table row, instead of evaluating it as the column names for the outer select statement and returning the actual values.
From what I have read in all of the forums discussing this kind of question (and there were many), there is really no way of getting this to work without prepared statements.
I can only think of one other way to do this, and that would be having a dedicated column on each table, where you concatenate the individual column values on INSERT or UPDATE, so you can simply select this one field instead of the full set of fields.
Seems like you have 3 questions here:
Getting a resultset with 1 row, 1 field: MYSQL has a CONCAT_WS function that works like this:
SELECT CONCAT_WS(',',Field1,Field2,Field3)
That will return "Field1Value, Field2Value, Field3Value"
I'm not sure how you are going to get these column names. Do you need to get them from a sql statement, a string, etc. ? You can get the table names `SHOW COLUMNS FROM tablename'. The Field column will have the column names.
Triggers are available in mysql (added in 5.0.2 I think): http://dev.mysql.com/doc/refman/5.0/en/triggers.html
First, to find out the columns' names in advance, assuming that you have the table's name, you can get them as any other query:
SHOW COLUMNS FROM your_table
Once you have the names you can do:
SELECT CONCAT(field1,',',field2,',',field3) AS newField FROM your_table