I need to include the table name in a SELECT statement, together with some columns and the unique identifier of the table.
I don't know if there is possible to take the table name from a select within that table or some kind of unique identifier.
How can I achieve this?
I thank you for your responses but I fixed this in this way (it was too easy actually)
select 'table1' as tableName, col1, col2 from anyTable;
You will need to query the system catalog of the database to find the primary key and all unique constraints of the table, then choose one that best suites your needs. You can expect to find 0, 1, or more such constraints.
For an Oracle database you'd use something like
select
c.constraint_name,
col.column_name
from
dba_constrants c,
dba_cons_columns col
where
c.table_name = 'YOURTABLE'
and c.constraint_type in ('P', 'U')
and c.constraint_name = col.constraint_name
order by
c.constraint_name,
col.position
For MySQL you would query INFORMATION_SCHEMA.TABLE_CONSTRAINTS and INFORMATION_SCHEMA.KEY_COLUMN_USAGE views in a similar manner.
this will give you all the table names from your database, you can tweak it as you see fit
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE'
Related
I'm trying to auto-increment table-name while creating a new table.
Below one, is the generic way to do it.
CREATE TABLE table_name (column_name column_type);
How can we add an auto-increment to table name like: table_name1, table_name2, etc?
There is no "auto incrementing" functionality with table names, you should handle it yourself. You can, for example, count the tables in your database with specific names and in specific schema:
SELECT count(*) FROM information_schema.tables WHERE table_schema = 'YOUR_SCHEMA' AND table_name LIKE '%YOUR_TABLE_NAME%';
Increase the number you got in result and create a new table.
Thanks to #errata, I have solved this problem. If I have tables with names: table_name1, table_name2, table_name_100, table_name_120.
I wanted to add an increment to a new table. So in the first part, I fetched the max count of the alpha-numeric table name.
SELECT MAX(CAST(SUBSTR(TRIM(table_name),12) AS UNSIGNED)) FROM information_schema.tables WHERE table_schema = '${userSchema}' AND table_name LIKE '%table_name%';
It returns, for example, 120 in the above case.
Use this and increment with 1 to new table_name.
I have a web application that has multiple tables. These tables and the values in their columns are stores in mysql tables with each mysql table representing one table in the application. Let's say the following is what I in mysql database have:
table1 with column1_1, column1_2, column1_3
table2 with column2_1, column2_2
table3 with column3_1, column3_2, column3_3, column3_4
I have a new requirement wherein I should be able to allow a user to make comments on any of the columns of any of the tables. For this I am creating a mysql table named 'comments' with following fields:
id
table_name (name of table on which comment is being made)
column_name (name of the column on which comment is being made)
Currently, table_name and column_name are varchar. I am wondering if there is a way to restrict table_name column to taking values of the currently existing table names viz. table1, table2 and table3 and also be able to refer to those tables using the entry in table_name. Similarly, for column_name, I want to be able to refer to column present in the other tables. Is there a way to do this?
On MySQL, you can get the names of the tables in a schema by using the following query:
SELECT table_name FROM information_schema.tables
WHERE table_schema = 'your_database_name';
You can also retrieve the names of the columns in a table with the query:
SELECT column_name
FROM information_schema.columns
WHERE table_schema = 'your_database_name' AND table_name = 'your_table';
According to MySQL's documentation, CHECK constraints cannot contain user-defined functions or subqueries (among other things).
Instead of using a CHECK constraint, what you can do is write a trigger that checks whether or not the inserted table_name is valid, and, if so,
check if the column_name belongs to that table.
I have two tables that have a huge list of columns. They are both the same structure, but different data. However, both tables have an index/auto-increment column that might be similar. Is there an easy way to run a command like this:
insert into table1 (select * from table2);
and have the insert ignore the auto-increment column from table 2? To avoid an error if there's a similar-value in the index column of tables 1 and 2? I want to copy everything over, and have new auto-increments for the table 2 data in table 1.
Alternatively, I don't care what the values are of the auto-increment index. If there was a way to merge the two tables and then re-generate unique AI columns that would also work.
I am aware I could get around this by specifying each field individually in both tables and leaving out the auto-increment column. I'm just wondering if there is an easier way to do this? If there isn't, is there an easy way of generating the field list/statement?
Here is the most efficient way I know of right now. Assuming the A.I. index is called "recno"
ALTER TABLE table1 DROP COLUMN recid;
ALTER TABLE table2 DROP COLUMN recid;
insert into table1 (select * from table2);
ALTER TABLE table1 ADD `recid` INT NOT NULL AUTO_INCREMENT [AFTER `column`], ADD PRIMARY KEY (`recid`);
ALTER TABLE table2 ADD `recid` INT NOT NULL AUTO_INCREMENT [AFTER `column`], ADD PRIMARY KEY (`recid`);
There's not really a way to do that. The * in the SELECT list means "all columns" in ordinal position. There's not exception for columns that meet specified criteria.
The same is true for an omitted list of columns that we're inserting into... it's all of the columns.
The most efficient way (in terms of database resources) to accomplish the specified goal is to list the columns, and omit the auto_increment column from the list.
INSERT INTO t (b,c,d,e) SELECT b,c,d,e FROM s ;
We can get a list of columns names for a table from information_schema.columns...
For example, to get a list of the column names in table2:
SELECT c.column_name
FROM information_schema.columns c
WHERE c.table_schema = 'mydatabase'
AND c.table_name = 'table2'
ORDER
BY c.ordinal_position
To exclude the auto_increment column from the list, we can add a WHERE clause, that excludes that column by it's name
WHERE c.column_name NOT IN ('my_autoincrement_column_name')
or we can check for 'auto_increment' occurring the EXTRA column
WHERE c.extra NOT LIKE '%auto_increment%'
To get a column list for each of the two tables, excluding the auto_increment columns, we could do something like this:
SET group_concat_max_len = 16777216 ;
SELECT GROUP_CONCAT( CONCAT('`',c.column_name,'`')
ORDER BY c.ordinal_position
SEPARATOR ','
) AS `-- column_list`
FROM information_schema.columns c
WHERE c.table_schema = 'mydatabase'
AND c.table_name IN ('table1','table2')
AND c.extra NOT LIKE '%auto_increment%'
GROUP
BY c.table_schema
, c.table_name
ORDER
BY c.table_schema
, c.table_name
EDIT
I'd take the column lists, and build a SQL query.
If we're going to make changes to table2 (dropping the auto_increment column as suggested in another answer to this question), and if we don't need to preserve the values in the column, the easiest change would be to just set all of the values in that column to NULL.
No need to modify table1.
We can remove the auto_increment attribute (and the NOT NULL constraint if that's specified) from the column in table2, and set the column to null. Assuming ai is the name of the auto_increment column, and assuming it's declared to be INT UNSIGNED datatype, we can do:
ALTER TABLE `table2` CHANGE `ai` `ai` INT UNSIGNED COMMENT '' ;
UPDATE `table2` SET `ai` = NULL ;
Then we can do an INSERT INTO table1 SELECT * FROM table2
And then add back the auto_increment attribute to the column in table2.
This approach is more expensive (in terms of the database resources) than a single INSERT ... SELECT.
Generating a column list is an extra step, but the resulting operation would be much more efficient. We could generate a list of columns from just the source table, and then replace the column name with literal NULL value...
INSERT INTO t SELECT NULL,b,c,d FROM s;
What I need to do is retrieve the maximum primary key of all tables in my database at once? That is, my result will be like if I executed the below 2 queries:
SHOW TABLES FROM DATABASE_NAME
SELECT MAX(PRIMARY_KEY) AS maxId FROM TABLE
That is
(first column = TableName , second column = MAX(PK) Of that table)
Pardon if I am doing something wrong. I just do not want to write 80 queries because my database has 80 tables.
If (and only if) your primary keys are AUTO INCREMENT variables you can do this:
SELECT TABLE_NAME, AUTO_INCREMENT
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'mydb'
Please pay attention to the situation below when choosing the method of retrieving that info and what you are going to do with it:
AUTO_INCREMENT value is stored in memory, so after a server restart, AUTO_INCREMENT value is reset to:
SELECT MAX(ai_col) FROM table_name FOR UPDATE;
This can break things if the database has missing FKs and, for example, you delete some rows that refer to other tables. You would end up by reusing the same id.
Refer to: https://dev.mysql.com/doc/refman/5.7/en/innodb-auto-increment-handling.html#innodb-auto-increment-initialization
SELECT table_schema, table_name, column_name, data_type, extra
FROM `columns`
WHERE table_schema = 'mydb'
AND extra LIKE '%auto_increment%'
Optionally JOIN this with Alnitak's Answer.
Current situation:
INSERT INTO othertbl
SELECT *
FROM tbl
WHERE id = '1'
So i want to copy a record from tbl to othertbl. Both tables have an autoincremented unique index. Now the new record should have a new index, rather then the value of the index of the originating record else copying results in a index not unique error.
A solution would be to not use the * but since these tables have quite some columns i really think it's getting ugly.
So,.. is there a better way to copy a record which results in a new record in othertbl which has a new autoincremented index without having to write out all columns in the query and using a NULL value for the index.
-hope it makes sense....-
Think you're gonna have to drop the * and specify the columns fella
If you're using SQL Server you could get a list of columns using
SELECT column_name+', ' from INFORMATION_SCHEMA.COLUMNS where table_name = 'tbl'
Building an insert statement using the result from the above should be easy.
You can dump the list of non-auto-increment columns for your table with this query, and then use it in the insert and select statements:
SELECT group_concat(column_name)
from INFORMATION_SCHEMA.COLUMNS
where table_schema = 'myschema'
and table_name = 'tbl'
and extra != 'auto_increment';
Try:
INSERT ...
SELECT *
FROM tbl
ON DUPLICATE KEY UPDATE `id`=NULL
http://dev.mysql.com/doc/refman/5.1/en/insert-select.html