alter table if fields is not already exist - mysql

alter table if field is not already exist
ALTER TABLE `table`
ADD( `abc` text NOT NULL,
`xyz` tinyint(1) NOT NULL,
);
if abc or xyz fields are already exist the can not be alter table
if it is possible ?

You can use a SHOW COLUMNS beforehand and construct your query accordingly, adding only fields that are missing.
Example output of SHOW COLUMNS:
mysql> SHOW COLUMNS FROM City;
+------------+----------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+----------+------+-----+---------+----------------+
| Id | int(11) | NO | PRI | NULL | auto_increment |
| Name | char(35) | NO | | | |
| Country | char(3) | NO | UNI | | |
| District | char(20) | YES | MUL | | |
| Population | int(11) | NO | | 0 | |
+------------+----------+------+-----+---------+----------------+
5 rows in set (0.00 sec)

I can't comment yet, so I post answer: try this link for detailed example. It queries information_schema.COLUMNS table for column information about database tables.

Related

MySql; proper way to update fields of a table

When trying to describe a table I get a table with missing information (see first table); what would be the best way to update that table in a way that looks like the second one? My SQL background is not so strong, so I'd love to hear ideas on how to do this
First table (how it is actually)
+-----------+------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------------+------+-----+---------+-------+
| config_id | int(10) unsigned | NO | | 0 | |
| scope | varchar(8) | NO | | default | |
| scope_id | int(11) | NO | | 0 | |
| path | varchar(255) | NO | | general | |
| value | text | YES | | NULL | |
+-----------+------------------+------+-----+---------+-------+
Second table (how it should be)
+-----------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+------------------+------+-----+---------+----------------+
| config_id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| scope | varchar(8) | NO | MUL | default | |
| scope_id | int(11) | NO | | 0 | |
| path | varchar(255) | NO | | general | |
| value | text | YES | | NULL | |
+-----------+------------------+------+-----+---------+----------------+
I see following differences between the two tables :
column config_id should be auto_increment and also primary key of the table
a (non-unique) index is missing on column scope
The following statement should change the table as required :
ALTER TABLE mytable
MODIFY COLUMN config_id INT auto_increment,
ADD PRIMARY KEY (config_id),
ADD INDEX idx_scope(scope)
;
PS : DEFAULT NULL does not make sense for config_id : since it is a primary key, your RDBMS will never allow it to be set to NULL.
Please note that this answer is based on the information you provided only. Running this statement will not necessarily make the table structures strictly equivalent, since there could be other differences that can not be seen in the representation that you provided. You can get a complete DDL statement describing the table using the SHOW CREATE TABLE mytable syntax.

Improve query performance in MySQL

I am posting this thread in order to have some advices regarding the performance of my SQL query.
I have actually 2 tables, one which called HGVS_SNP with about 44657169 rows and another on run table which has an average of 2000 rows.
When I try to update field Comment of my run table it takes lot's of time to perform the query. I was wondering if there is any method to increase my SQL query.
Structure of HGVS_SNP Table:
+-----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| snp_id | int(11) | YES | MUL | NULL | |
| hgvs_name | text | YES | | NULL | |
| source | varchar(8) | NO | | NULL | |
| upd_time | varchar(32) | NO | | NULL | |
+-----------+-------------+------+-----+---------+-------+
My run table has the following structure:
+----------------------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------------+--------------+------+-----+---------+-------+
| ID | varchar(7) | YES | | NULL | |
| Reference | varchar(7) | YES | MUL | NULL | |
| HGVSvar2 | varchar(120) | YES | MUL | NULL | |
| Comment | varchar(120) | YES | | NULL | |
| Compute | varchar(20) | YES | | NULL | |
+----------------------+--------------+------+-----+---------+-------+
Here's my query:
UPDATE run
INNER JOIN SNP_HGVS
ON run.HGVSvar2=SNP_HGVS.hgvs_name
SET run.Comment=concat('rs',SNP_HGVS.snp_id) WHERE run.Compute not like 'tron'
I`m guessing since you JOIN a text column with a VARCHAR(120) column that you don`t really need a text column. Make it a VARCHAR so you can index it
ALTER TABLE `HGVS_SNP` modify hgvs_name VARCHAR(120);
ALTER TABLE `HGVS_SNP` ADD KEY idx_hgvs_name (hgvs_name);
This will take a while on large tables
Now your JOIN should be much faster,also add an index on compute column
ALTER TABLE `run` ADD KEY idx_compute (compute);
And the LIKE is unnecessary,change it to
WHERE run.Compute != 'tron'

"key column doesn't exist in table"

I'm making a database in MySQL in class and I'm having trouble adding foreign keys to my tables. I already added most of the foreign keys to my tables when I created the tables but obviously I couldn't add all of them in the creation process. I'm trying to add the remaining foreign keys with the below method.
ALTER TABLE ORDERS
ADD FOREIGN KEY (customer_sid) REFERENCES CUSTOMER(SID);
For some reason the error message listed in the title keeps popping up. The code is below. I can see the tables are coming out a bit funny but if you read them from left to right you can see what it says. What do you think?
mysql> show columns from games;
+------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+---------+----------------+
| gameID | int(11) | NO | PRI | NULL | auto_increment |
| videoGames | varchar(30) | NO | | NULL | |
| year | int(11) | NO | | NULL | |
| genreID | int(11) | NO | MUL | NULL | |
| companyID | int(11) | NO | MUL | NULL | |
| directorID | int(11) | NO | MUL | NULL | |
+------------+-------------+------+-----+---------+----------------+
6 rows in set (0.01 sec)
mysql> show columns from consoles;
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| consoleID | int(11) | NO | PRI | NULL | auto_increment |
| console | varchar(20) | NO | | NULL | |
| yearReleased | int(11) | NO | | NULL | |
+--------------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
mysql> alter table games
-> add foreign key(consoleID) references consoles(consoleID);
ERROR 1072 (42000): Key column 'consoleID' doesn't exist in table
There is no field consoleID in your table games. You need to create it before trying to add a constraint on it. This will add consoleID and create the constraint:
ALTER TABLE games ADD COLUMN consoleID INTEGER NOT NULL;
ALTER TABLE games ADD FOREIGN KEY (consoleID) REFERENCES consoles(consoleID);
You should think about adding a third table where you associate consoles with games because some games are multiplateform. :)

Create table with date column

I want to create a student table with column 'student_birthday' and its format should be dd-mm-yy.
create table `student`.`studentinfo`(
`student_id` int(10) not null auto_increment,
`student_name` varchar(45) not null,
`student_surname` varchar(45) not null,
`student_birthday` date(???),
(some lines of code)
primary key(student_id));
what should be inputted in the (???) to get the right format above?
Just use "DATE" without the brackets. The brackets are only needed for certain column types where you want to specify the maximum number of bytes/characters that can be stored.
For MySQL, it's documented at https://dev.mysql.com/doc/refman/5.7/en/date-and-time-types.html
The following example will explain your problem. I am using MySQL 5.7.18.
Firstly I have described the structure of users table as I am going to create posts table with FOREIGN KEY.
Later I created posts table and it has a DATE field named created with many other columns.
Finally I inserted 1 row in the newly created table.
mysql> desc users;
+-------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+-------+
| id | bigint(20) | NO | PRI | NULL | |
| fname | varchar(50) | NO | | NULL | |
| lname | varchar(50) | NO | | NULL | |
| uname | varchar(20) | NO | | NULL | |
| email | text | NO | | NULL | |
| contact | bigint(12) | NO | | NULL | |
| profile_pic | text | NO | | NULL | |
+-------------+-------------+------+-----+---------+-------+
7 rows in set (0.00 sec)
mysql> CREATE TABLE posts(id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, title text NOT NULL, description text NOT NULL, posted_by bigint, FOREIGN KEY(posted_by) REFERENCES users(id) ON DELETE CASCADE ON UPDATE RESTRICT , created DATE);
Query OK, 0 rows affected (0.01 sec)
mysql> desc posts;
+-------------+------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------+------+-----+---------+----------------+
| id | bigint(20) | NO | PRI | NULL | auto_increment |
| title | text | NO | | NULL | |
| description | text | NO | | NULL | |
| posted_by | bigint(20) | YES | MUL | NULL | |
| created | date | YES | | NULL | |
+-------------+------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
mysql> INSERT INTO posts(title, description, posted_by, created) values("Getting started with MySQL", "Excellent Database system", 1, "2017-05-26");
Query OK, 1 row affected (0.00 sec)
mysql> select * from posts;
+----+----------------------------+---------------------------+-----------+------------+
| id | title | description | posted_by | created |
+----+----------------------------+---------------------------+-----------+------------+
| 1 | Getting started with MySQL | Excellent Database system | 1 | 2017-05-26 |
+----+----------------------------+---------------------------+-----------+------------+
1 row in set (0.00 sec)
mysql>
The datatype date on its own is enough to represent a date value. The format will matter when you are displaying the data, for which you can use the FORMAT function on your date column.
I should add that there is a certain amount of flexibility as to the format when inserting date time literals as documented here.

mysql trigger when no match found

I'm trying to setup a mysql trigger. So lets assume the table is like this
mysql> explain users;
+------------+-------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(30) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
| purge_date | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+------------+-------------+------+-----+-------------------+-----------------------------+
and
mysql> explain users_details;
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(30) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.00 sec)
so the trigger i have setup will create a purge_date of NOW on the users table when something is removed from the users_details table. This is fine.
The issue is that sometimes the data for the users_details table comes through incorrectly and then the users update it so then i need to remove the purge_date if they re-insert the data. Now I have made this trigger
CREATE TRIGGER purge_fix AFTER INSERT ON users_details
FOR EACH ROW
BEGIN
UPDATE users
SET purge_date= '0000-00-00 00:00:00'
WHERE users.name = NEW.name;
END;
Which works fine but in some situations there will not be a link between the users_details table and the users table (it will be created at a later stage) so my question is, as the trigger will fail in some situations (which is 100% fine by me), will I be breaking something having the trigger failing?