Pass Column value as a variable in MySQL - mysql

In Mysql, I am tring to find a way to pass a column value into a variable. Then use the variable as a table name in another query...Below is a MsSQL version of it, Please help me find a Mysql equivalent.
declare #tblname1 varchar(400)
set #tblname1=(SELECT companyname from companies where id=5)
exec(' SELECT sh.streetname FROM '+#tblname1+' sh WHERE sh.id IN (SELECT id from allstreets)')` `

Take a look at the following: https://dev.mysql.com/doc/refman/5.7/en/sql-syntax-prepared-statements.html
set #tblname1=(SELECT companyname from companies where id=5);
PREPARE stmt1 FROM CONCAT('SELECT sh.streetname FROM ', #tblname1, ' sh WHERE sh.id IN (SELECT id from allstreets)');
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
Also, based on your question, I must say that creating a table for each companyname in the company table is a poor design and can only lead to frustration and disappointment.

Related

Create a new table with a column for every element in another table

I have create a table in MySQL where i have all the names of data I'm going to bring in from FRED data.
Now I want to make a new table, where the 1504 names in my example table above, each has one column.
AAA AAA10M AAAFFM ADBJORNS and so on.
So every name in fred_namecol should get one column each with numeric as value. Is there a easy way to do this instead of writing everyone manually?
Maybe there is a way too loop trough each name and make a column for them into a new table?
Yes. There is a way.
In the following query; replace WRITE_YOUR_TABLE_NAME_HERE with the name of the table which contains fred_namecol column:
drop table if exists columns_over_1000;
set #prefix = 'CREATE TABLE columns_over_1000 (';
set #suffix = '\n);';
select #create_table_sql := concat(
#prefix,
group_concat('\n `', fred_namecol, '` INT'),
#suffix)
from `WRITE_YOUR_TABLE_NAME_HERE`;
PREPARE stmt1 FROM #create_table_sql;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
select * from columns_over_1000;

How to describe table that I only have part of name?

I have an old script that creates each day a table and store data in it.
The table names are like this today-date-some-other-string, i.e : 02-02-2018-other-string.
The question is, how could I describe the structure of that table despite I only have today's date? I mean is there a way to do something like this :
DESC WHERE Table like "02-02-2018%"
Thank you.
In mysql you could use prepared statements for example
set #sql = concat('describe ' , (select table_name
from information_schema.tables
where table_name like 'users' and table_schema = 'sandbox')
,';');
prepare sqlstmt from #sql;
execute sqlstmt;
deallocate prepare sqlstmt;

Mysql sum all columns starting with some letters

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;

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