Mysql sum all columns starting with some letters - mysql

I am trying add one column in my Mysql database that sums all the columns starting by 'tokenvalid' which can take the value of 1 or 0.
And let's say I have 50 columns like that in my database (i.e. tokenvalid1, tokenvalid2 ...., tokenvalide50) with other columns between.
Please find below the code I would like to implement. I know that is not correct at all but it is just to give you an idea of what I am trying to do.
Thank you for your help!
'SELECT *, sum(column_name LIKE "tokenvalid"%) as total FROM points WHERE 1'

This post should help you. The post describes how to get the columns and then query for results.
MySQL Like statement in SELECT column_name

Something like this should help you.
SET #colname = (SELECT GROUP_CONCAT(`column_name`) from INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='points' AND `column_name` LIKE 'tokenvalid%');
SET #table = 'points';
SET #query = CONCAT('SELECT SUM(',#colname,') FROM ', #table);
PREPARE stmt FROM #query;
EXECUTE stmt;
Similar to this answer by RocketDonkey

If the string is in your external application (like PHP), sure, just construct the MySQL statement.
If the string is inside a MySQL table, you can't. MySQL has no eval() or such function. The following is impossible:
Suppose you have a table 'queries' with a field "columnname" that refers to one of the column names in the table "mytable". There might be additional columns in 'queries' that allow you to select the columnname you want...
INSERT INTO queries (columname) VALUES ("name")
SELECT (select columnname from queries) from mytable
You can however work with PREPARED STATEMENTS. Be aware this is very hacky.
SELECT columnname from queries into #colname;
SET #table = 'mytable';
SET #s = CONCAT('SELECT ',#colname,' FROM ', #table);
PREPARE stmt FROM #s;
EXECUTE stmt;

Related

How can I use SQL pivot command to convert a single column of rows to a single row of columns?

I have seen a lot of similar questions but not exactly what I'm looking for. I need to convert a single column of
I'm using
SELECT Column_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE Table_name = 'LibraryInventory'
to get the column names of my table. However, they're being returned in a single row such as this
ID
-----|
NAME
-----|
TITLE
-----|
I need a way to have these put into a long single row of columns so I can use it in Java how I'm planning like: |ID| NAME| TITLE|
Does anyone know a simple way to do this? I've seen people use pivot however they have much more complicated tables so struggled to understand it.
You can use a prepared statement:
SELECT #query :=
group_concat(concat('''', Column_name, ''''))
FROM
INFORMATION_SCHEMA.COLUMNS
WHERE Table_name = 'LibraryInventory' ;
set #query = concat(' SELECT ', #query, ''';');
prepare stmt from #query;
execute stmt;

Please explain these SQL statements

Please explain me the below example
SELECT GROUP_CONCAT(COLUMN_NAME)
FROM information_schema.`COLUMNS` C
WHERE table_name = 'table_name'
AND COLUMN_NAME =('columns_name') INTO #COLUMNS;
SET #table = 'table_name';
SET #s = CONCAT('SELECT ',#columns,' FROM ', #table);
PREPARE stmt FROM #s;
This pattern is all about creating dynamic (prepared in MySQL parlance) queries based on the names of columns in a particular table. INFORMATION_SCHEMA is a built-in database with read-only tables describing all the tables in all databases on the MySQL server.
The first query in your sequence retrieves a text string in the local variable #COLUMNS with a value like
id,name,value,description
for a table named table_name with those four columns.
The third one retrieves a string in the local variable #s with a value containing a query like
SELECT id,name,value,description FROM table_name
The fourth one, PREPARE, gets ready to do EXECUTE stmt, which runs the query. You can read about PREPARE and EXECUTE here.
The whole sequence of queries in your question does almost exactly the same thing as SELECT * FROM table_name.
There's a defect in your first query. You should add AND TABLE_SCHEMA = DATABASE() to its WHERE clause. Otherwise, you may pick up columns from tables named table_name in multiple databases.

Return Column and Table holding value

I can write a query to search for a table that has a particular column in a DB
SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME like '%A'
but My Question is:
can I search an entire DB for a value in a column?
So I'm unsure the name of the column and I am unsure the name of the DB table but I know the value is 'Active'
Yes, you can. In that case, you need to prepare dynamic query once you get list of tables, which consists column, which actually you are looking for.
Now create a cursor for
SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE COLUMN_NAME like '%A'
Using above cursor loop below
SET #s = CONCAT("select count(*) from [tablename] where [columnname] like ","'%SOMETHING%'");
PREPARE stmt FROM #s
execute stmt;
DEALLOCATE PREPARE stmt;

SQL - Select rows that contain a NULL value in a non-nullable column

I'm hoping somebody can help me with a script / query, the target DB is mySQL.
The database I am working with does not conform to it's own constraints and is in the process of being moved to MS SQL. What I am looking to find is a query that can be run against a table which looks for rows that contain a null value in a column that does not allow nulls, which in turn will assist with SSIS DFT debugging times.
Many thanks.
Try:
SELECT group_concat(`COLUMN_NAME`) as myList
FROM `INFORMATION_SCHEMA`.`COLUMNS`
WHERE `TABLE_SCHEMA`='yourdatabasename'
AND `TABLE_NAME`='yourtablename'
-- AND `IS_NULLABLE`='NO'
into #colname;
SET #query = CONCAT('SELECT ',#colname,' FROM yourtablename');
PREPARE stmt FROM #query;
EXECUTE stmt;

How can I "select *" from a table in MySQL but omit certain columns?

I have a table with the following columns:
id,name,age,surname,lastname,catgory,active
Instead of: SELECT name,age,surname,lastname,catgory FROM table
How can I make something like this: SELECT * FROM table [but not select id,active]
While many say it is best practice to explicitly list every column you want returned, there are situations where you might want to save time and omit certain columns from the results (e.g. testing). Below I have given two options that solve this problem.
1. Create a Function that retrieves all of the desired column names: ( I created a schema called functions to hold this function)
DELIMITER $$
CREATE DEFINER=`root`#`%` FUNCTION `getTableColumns`(_schemaName varchar(100), _tableName varchar(100), _omitColumns varchar(200)) RETURNS varchar(5000) CHARSET latin1
BEGIN
SELECT GROUP_CONCAT(COLUMN_NAME) FROM information_schema.columns
WHERE table_schema = _schemaName AND table_name = _tableName AND FIND_IN_SET(COLUMN_NAME,_omitColumns) = 0 ORDER BY ORDINAL_POSITION;
END
Create and execute select statement:
SET #sql = concat('SELECT ', (SELECT
functions.getTableColumns('test', 'employees', 'age,dateOfHire')), ' FROM test.employees');
PREPARE stmt1 FROM #sql;
EXECUTE stmt1;
2. OR without writing a function you could:
SET #sql = CONCAT('SELECT ', (SELECT GROUP_CONCAT(COLUMN_NAME) FROM
information_schema.columns WHERE table_schema = 'test' AND table_name =
'employees' AND column_name NOT IN ('age', 'dateOfHire')),
' from test.eployees');
PREPARE stmt1 FROM #sql;
EXECUTE stmt1;
*Replace test with your own schema name
**Replace employees with your own table name
***Replace age,dateOfHire with the columns you want to omit (you can leave it blank to return all columns or just enter one column name to omit)
** **You can adjust the lengths of the varchars in the function to meet your needs
The only way to do that that I know if is to enumerate each column you do want... no negative filters that I'm aware of.
select name, age, surname, lastname, category from table
you can't do that, sorry. Actually you shouln't have done it if you could - specifying these things explicitly is always better, assume other developer adds new field and your application will fail
You are too advanced.
The only data language that I have seen that supports your syntax is the D language with its "...ALL BUT ..." construct:
Wikipedia - D Language Specification
There are some reference implementations available, but mostly for teaching purposes.
Unless there's some special extension in MySql you cannot do that. You either get all, or have to explicitly state what you want. It is best practice to always name columns, as this will not alter the query behaviour even if the underlying table changes.
There is no SQL syntax to support:
select * from table but not select id,active
If you want all but one or more columns, you have to explicitly define the list of columns you want.
You should not be using select * anyway. Enumerate the columns you want and only the columns you want, that is the best practice.
SET #sql = CONCAT('SELECT ',
(SELECT REPLACE(GROUP_CONCAT(COLUMN_NAME), '<columns_to_delete>,', '')
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = '<table>'
AND TABLE_SCHEMA = '<database>'),
' FROM <table>');
PREPARE stmt1 FROM #sql;
EXECUTE stmt1;
I'm fairly certain you can't. Probably the best way I can think of is to create SELECT name, age, surname, lastname, category FROM table as a view, then just SELECT * FROM view. I prefer to always select from a view anyway.
However, as others have pointed out, if another column gets added to the view your application could fail. On some systems as well (PostgreSQL is a candidate) you cannot alter the table without first dropping the view so it becomes a bit cumbersome.
If the reason is to avoid column duplication error without having to specify a long list of columns:
temporarily change the name of column that is a duplicate to enable the view to be created.
delete the duplicate column from the select and save view
rename the changed column name
If the reason is simply to omit a one or more columns:
create view and delete column/s from select