MySQL Notes
MySQL Notes
MySQL Database
MySQL is a fast, easy-to-use RDBMS being used for many small and big businesses.
MySQL is developed, marketed and supported by MySQL AB, which is a Swedish
company. MySQL is becoming so popular because of many good reasons −
MySQL is released under an open-source license. So you have nothing to pay to
use it.
MySQL is a very powerful program in its own right. It handles a large subset of
the functionality of the most expensive and powerful database packages.
MySQL uses a standard form of the well-known SQL data language.
MySQL works on many operating systems and with many languages including
PHP, PERL, C, C++, JAVA, etc.
MySQL works very quickly and works well even with large data sets.
MySQL is very friendly to PHP, the most appreciated language for web
development.
MySQL supports large databases, up to 50 million rows or more in a table. The
default file size limit for a table is 4GB, but you can increase this (if your
operating system can handle it) to a theoretical limit of 8 million terabytes (TB).
MySQL is customizable. The open-source GPL license allows programmers to
modify the MySQL software to fit their own specific environments.
Practice Tables
create table suppliers(supplier_id int,supplier_name varchar(40),
contact_name varchar(40), city varchar(40));
Output:
DESCRIBE tableName;
Desc table name;
Chapter 2: Data Types
A data type is a set of representable values. Each value belongs to one data type.
Items that can be referenced by a name, such as SQL parameters, columns, fields,
attributes, and variables, also have declared types.
Numbers
Numeric types can be either integers or floating point numbers.
1. Integers
1. TINYINT
2. SMALLINT
3. MEDIUMINT
4. INTEGER
5. BIGINT
2. Floating points
1. FLOAT
2. DOUBLE
3. DECIMAL
Integers
Integers are a subset of the real numbers. They are written without a fraction or a
decimal component. Integers fall within a set Z = {..., -2, -1, 0, 1, 2, ...} Integers are
infinite. Computers can practically work only with a subset of integer values, because
computers have finite capacity. Integers are used to count discrete entities. We can
have 3, 4, 6 cars, but we cannot have 3.33 cars. We can have 3.33 kilograms.
Byte
Data type Minimum value Maximum value
s
The integer types differ in their storage. We can choose values that fit our
requirements.
We have created a temporary Ages table. This will be only a temporary testing table,
so there will be only a few rows. The SMALLINT will suffice. We do not know anyone
older than 130 years, so TINYINT will be OK for the Age column.
Output:
Trying to insert a value outside the range of the column type leads to an error.
When we are dealing with ages, we do not need negative integer values. MySQL
supports unsigned integers.
Byte Minimum
Data type Maximum value
s value
TINYINT 1 0 255
SMALLINT 2 0 65535
MEDIUMINT 3 0 16777215
INTEGER 4 0 4294967295
1844674407370955161
BIGINT 8 0
5
We use the SQL statement to change the Age column to have a TINYINT
UNSIGNED data type.
output
mysql> SELECT * FROM Ages;
output:
We have inserted a hypothetical age 128. Now the column accepts it.
Floating point numbers represent real numbers in computing. Real numbers measure
continuous quantities, like weight, height or speed.
MySQL has floating point types for approximate values: FLOAT and DOUBLE and fixed-
point types for exact values: DECIMAL and NUMERIC.
FLOAT is a single precision floating point number. MySQL uses four bytes to store
a FLOAT value.
DOUBLE is a double precision floating point number. MySQL uses eight bytes to store
a DOUBLE value.
DECIMAL and NUMERIC types store exact numeric data values. These types are used
when it is important to preserve exact precision, for example with financial data. In
MySQL, NUMERIC is a synonym for DECIMAL.
Floats, doubles, and decimals may have specified their precision and scale.
In DECIMAL[M, D]
A column with DECIMAL(3, 1), we can insert numbers with maximum of three digits:
before and one after the decimal point.
mysql> CREATE TABLE Numbers (Id TINYINT, Floats FLOAT, Decimals DECIMAL(3, 2));
We create a table in which we are going to store a few floats and decimals.
mysql> INSERT INTO Numbers VALUES (1, 1.1, 1.1), (2, 1.1, 1.1), (3, 1.1, 1.1);
output:
output:
The two results differ. The decimal calculation is more precise. Due to some internal
rounding, the sum of floats is not accurate.
Date & time values
MySQL has data types for storing dates and times: DATE, TIME, DATETIME, YEAR,
and TIMESTAMP. MySQL tries to interpret date and time values in several formats but
the date parts must always be given in year/month/day order. MySQL automatically
converts a date or time value to a number if the value is used in a numeric context
and vice versa.
Date
The DATE is used to store dates. MySQL retrieves and displays date values in YYYY-
MM-DD format. The supported range is from 1000-01-01 to 9999-12-31.
The DATE() function returns the date part of the date and time value.
The ADDDATE() function adds days to a date. It returns the calculated date.
Dates are displayed in MySQL in one format, but we can use various date formats in
our SQL statements. The YYYY-MM-DD is the standard format. It is possible to use any
punctuation character between the date parts.
We have used multiple formats to insert dates into the table. MySQL uses one format
to display the dates.
Time
The TIME data type is used to display time in MySQL. It shows values
in HH:MM:SS format.
It is because TIME data type can be used to denote time intervals. This is also why we
can have negative time values.
mysql> SELECT CURTIME();
Output
The TIMEDIFF() function is used to subtract two time values in timestamp format.
We can use the TIME() function to extract the time part of the date and time value.
We can write time values in different formats too. The first parameter is a time value
in a string format without delimiters. The second is a time value specified as a
number.
Datetime
The DATETIME values contain both date and time. MySQL retrieves and displays
values in YYYY-MM-DD HH:MM:SS format. The supported range is from 1000-01-01
00:00:00 to 9999-12-31 23:59:59.
‘2017@01@31 Date
11@12@12' Time
MySQL displays date and time in only one format. But in our SQL statements, we can
use different formats. Any punctuation character may be used as the delimiter
between date parts or time parts. In our case, we have used the @ character.
Year
The YEAR is a data type used for representing years. MySQL displays YEAR values
in YYYY format. It allows us to assign values to YEAR columns using either strings or
numbers. The allowable range is from 1901 to 2155, or 0000. Illegal year values are
converted to 0000.
Timestamp
TIMESTAMP(14) YYYYMMDDHHMMSS
TIMESTAMP(12) YYMMDDHHMMSS
TIMESTAMP(10) YYMMDDHHMM
TIMESTAMP(8) YYYYMMDD
TIMESTAMP(6) YYMMDD
TIMESTAMP(4) YYMM
TIMESTAMP(2) YY
The TIMESTAMP data type offers automatic initialisation and updating. We can restrict
this data type to have only automatic initialisation or automatic update only.
When we insert a TIMESTAMP value into a table, MySQL converts it from your
connection’s time zone to UTC for storing.
mysql> CREATE TABLE Prices(Id TINYINT PRIMARY KEY, Price DECIMAL(8, 2), Stamp
TIMESTAMP);
mysql> INSERT INTO Prices VALUES(1, 234.34,'2019-10-01- 00:00:01');
mysql> INSERT INTO Prices VALUES(2, 144.34,'2019-01-01- 00:00:01');
We create a table with a TIMESTAMP column. We insert two rows into the table. The
Stamp column is not included in the SQL statements. MySQL automatically fills the
column.
We execute the SQL statement to update the Price column in the first row.
The timestamp of the first column was updated. If we wanted to turn off the auto-
update of the TIMESTAMP, we could use the Stamp TIMESTAMP DEFAULT
CURRENT_TIMESTAMP SQL code when creating the table.
Strings
CHAR
VARCHAR
BINARY
VARBINARY
BLOB
TEXT
ENUM
SET
Char
A CHAR is a fixed length character data type. It is declared with a length, CHAR(x),
where x can be between 0 to 255. CHAR always uses the same amount of storage
space per entry.
In the above SQL code, we have created a Chars table which has one column of
the CHAR data type. The maximum length is set to three characters.
varchar
VARCHAR data types stores variable-length strings. The length of the string can be
from 0 to 65535. VARCHAR values are not padded when they are stored. Trailing
spaces are retained when values are stored and retrieved. Most shorter string data
types are stored in this data type; for example emails, names of people, of
merchandise, or addresses.
We can see that names in a VARCHAR column type are stored in variable length. This
saves disk space.
BINARY and VARBINARY are binary byte data types. They contain byte strings rather
than character strings. They have no character sets. Sorting and comparison are
based on the numeric values of the bytes in the values. The range of the BINARY data
types is from 0 to 255. It stores values in fixed length. The range of the VARBINARY is
from 0 to 65535.
Blob
A BLOB is a binary large object data type. It can hold a variable amount of binary
data. It can be used to store binary data like images or documents. BLOB has four
types:
Range in
Blob type
bytes
TINYBLOB 0 – 255
BLOB 0 - 65535
MEDIUMBLOB 0 - 16777215
LONGBLOB 0 - 4294967295
With the help of the LOAD_FILE() function, we insert an image into the Images table.
mysql> SELECT Img FROM Images WHERE Id=1 INTO DUMPFILE 'C:\ProgramData\
MySQL\MySQL Server 8.0\Uploads/image_bck.jpg';
Text
A TEXT datatype is used for storing large textual data. For example articles, blogs, or
pages. TEXT values are best used when VARCHAR and other string-based data objects
are insufficient to handle storing the desired amount of information.
Range in
Blog type
bytes
TINYTEXT 0 - 255
TEXT 0 - 65535
MEDIUMTEXT 0 - 16777215
LONGTEXT 0 - 4294967295
Enum
The ENUM is a string object with a value chosen from a permitted list of values. They
are enumerated explicitly in the column specification. We can insert only one value
from the list.
Since 'Large' was not mentioned in the list, we get an error message.
mysql> SELECT * FROM Sizes;
We have two regular values in the table.
Example:
Set
A SET is a string object that can have zero or more values, each of which must be
chosen from a list of permitted values. It is similar to the ENUM data type. The
difference is that it can contain zero or more values from the list of permitted values.
mysql> CREATE TABLE Letters(Let SET('a', 'b', 'c', 'd', 'e'));
Example:
mysql> CREATE TABLE Letters(Let SET('a', 'b', 'c', 'd', 'e'),stu_no int);
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (1, 'Audi A1', '20000');
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (2, 'Audi A1', '15000');
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (3, 'Audi A2', '40000');
INSERT INTO CAR (`car_id`, `name`, `price`) VALUES (4, 'Audi A2', '40000');
SELECT DISTINCT `name`, `price` FROM CAR;
DISTINCT works across all columns to deliver the results, not individual columns. The
latter is often a misconception of new SQL developers. In short, it is the distinctness at
the row-level of the result set that matters, not distinctness at the column-level. To
visualize this, look at "Audi A1" in the above result set.
INSERT INTO stack (`id`, `username`, `password`) VALUES (1, 'Foo', 'hiddenGem');
INSERT INTO stack (`id`, `username`, `password`) VALUES (2, 'Baa', 'verySecret');
Query
SELECT id FROM stack;
Result
Output:
Or with IF
SELECT st.name, st.percentage, IF(st.percentage >= 35, 'Pass', 'Fail') AS `Remark`
FROM student AS st ;
N.B
IF(st.percentage >= 35, 'Pass', 'Fail')
This means : IF st.percentage >= 35 is TRUE then return 'Pass' ELSE return 'Fail'
When a LIMIT clause contains two numbers, it is interpreted as LIMIT offset, count.
So, in this example the query skips two records and returns one.
Output:
Note:
The values in LIMIT clauses must be constants; they may not be column values.
Note
BETWEEN uses >= and <=, not > and <.
Query
mysql> select supplier_id,supplier_name from suppliers where supplier_id in(select
supplier_id from items where item_name = 'Keyboard' and price >=400);
Chapter 4: NULL
We have seen the SQL SELECT command along with the WHERE clause to fetch
data from a MySQL table, but when we try to give a condition, which compares the
field or the column value to NULL, it does not work properly.
To handle such a situation, MySQL provides three operators −
IS NULL − This operator returns true, if the column value is NULL.
IS NOT NULL − This operator returns true, if the column value is not NULL.
<=> − This operator compares values, which (unlike the = operator) is true
even for two NULL values.
The conditions involving NULL are special. You cannot use = NULL or != NULL to
look for NULL values in columns. Such comparisons always fail because it is
impossible to tell whether they are true or not. Sometimes, even NULL = NULL fails.
To look for columns that are or are not NULL, use IS NULL or IS NOT NULL.
To find the records where the stu_no column is or is not NULL, the queries should be
written as shown in the following program.
The limit keyword is used to limit the number of rows returned in a query result.
It can be used in conjunction with the SELECT, UPDATE OR DELETE commands LIMIT
keyword syntax
HERE
Let's suppose that we want to get a limited number of members starting from the
middle of the rows, we can use the LIMIT keyword together with the offset value to
achieve that.
Also notice that the ORDER BY clause may be important in order to specify the first
rows of the result set that will be presented (when ordering by another column).
The first argument represents the row from which the result set rows will be
presented – this number is often mentioned as an offset, since it represents the row
previous to the initial row of the constrained result
set. This allows the argument to receive 0 as value and thus taking into consideration
the first row of the nonconstrained
result set.
the second argument specifies the maximum number of rows to be returned in the
result set (similarly to the one argument's example).
Example:
SELECT * FROM stu_tbl ORDER BY stu_no ASC LIMIT 2, 3
Notice that when the offset argument is 0, the result set will be equivalent to a one
argument LIMIT clause. This means that the following 2 queries:
Notice that in this alternative syntax the arguments have their positions switched:
the first argument represents the number of rows to be returned in the result set;
the second argument represents the offset.
Chapter 7: Creating databases
CREATE DATABASE Creates a database with the given name CREATE SCHEMA This is
a synonym for CREATE DATABASE IF NOT EXISTS Used to avoid execution error, if
specified database already exists create_specification options specify database
characteristics such as CHARACTER SET and COLLATE(database collation)
Example:
CREATE DATABASE movies;
Note: you can also use the command CREATE SCHEMA instead of CREATE DATABASE
Now let's improve our SQL query adding more parameters and specifications.
IF NOT EXISTS
A single MySQL server could have multiple databases. If you are not the only one
accessing the same MySQL server or if you have to deal with multiple databases there
is a probability of attempting to create a new database with name of an existing
database.
When IF NOT EXISTS is used, database is created only if given name does not clash
with an existing database's name. Without the use of IF NOT EXISTS MySQL throws
an error.
Collation is set of rules used in comparison. Many people use MySQL to store data
other than English. Data is stored in MySQL using a specific character set. The
character set can be defined at different levels in server , database , table and
columns.
You need to select the rules of collation which in turn depend on the character set
chosen.
For instance, the Latine1 character set uses the latin1_swedish_ci collation which is
the Swedish case insensitive order.
The best practice while using local languages like Arabic , Chinese etc is to select
Unicode (utf-8) character set which has several collations or just stick to default
collation utf8-general-ci.
You can find the list of all collations and character sets
SHOW CHARACTER SET;
You can see list of existing databases by running following SQL command.
SHOW DATABASES
Login to the MySQL server with root user with shell access and create a new user
named “rahul”. Below command will allow accessing MySQL server to user rahul from
localhost system only.
Now assign the privileges to the specific database. Below command will allow all
privileges on database “mydb” to user rahul.
After creating user and assigning proper privileges, make sure to reload privileges.
C:\Users\sathish>mysql -u sow1 -p
Enter password: ********
MySQL is an open source database software widely used for data storage. Sometimes
we forgot MySQL root password. So don’t be panic, This tutorial will help you to reset
MySQL root password with simple steps.
First of all, you are required to stop running MySQL server. Use one of the following
commands to stop MySQL server on your Linux system.
mysql> quit
# mysql -u root -p
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
Alternatively, you can select the database on the command line when we invoke
mysql.
Just specify its name after any connection parameters that you might
need to provide. For example:
shell> mysql -h host -u user -p menagerie
Enter password: ********
Chapter 8: Using Variables
Introduction to MySQL user-defined variables
Sometimes, you want to pass a value from an SQL statement to another SQL statement.
To do this, you store the value in a MySQL user-defined variable in the first statement and
refer to it in the subsequent statements.
The user-defined variables are not case-sensitive. It means that the @id and @ID are the
same.
You can assign the user-defined variable to a certain data types such as integer, floating
point, decimal, string or NULL.
A user-defined variable defined by one client is not visible by other clients. In other words,
an user-defined variable is session-specific.
Note that the user-defined variables are the MySQL-specific extension to SQL standard.
They may not be available in other database systems.
You can use either := or = as the assignment operator in the SET statement.
SET @counter := 100;
The second way to assign a value to a variable is to use the SELECT statement.
In this case, you must use the := assignment operator because, within the
SELECT statement, MySQL treats the = operator as the equal operator.
SELECT @variable_name := value;
After the assignment, you can use the variable in the subsequent statement
where an expression is permitted e.g.,
in WHERE clause, INSERT or UPDATE statement.
The following statement uses the @msrp variable to query the information of the most
expensive product.
SELECT item_id, item_name, qty, price FROM items WHERE qty = @msrp;
SELECT item_id, item_name, qty, price FROM items WHERE price < @msrp;
Sometimes, you want to insert a row into a table, get the last insert id, and use it for
inserting data into another table. In this case, you can use the user-defined variable to
store the most recent id generated by an AUTO_INCREMENT column as follows.
SELECT @id:=LAST_INSERT_ID();
A user-defined variable can hold a single value only. If the SELECT statement returns
multiple values, the variable will take the value of the last row in the result.
/*
This is a
multiple-line comment
*/
Example:
SELECT * FROM t1; -- this is comment
The -- method requires that a space follows the -- before the comment begins,
otherwise it will be interpreted as a command and usually cause an error.
#This comment works
/*This comment works.*/
--This comment does not.
Chapter 10: INSERT
Section 10.1: INSERT, ON DUPLICATE KEY UPDATE
When you insert a new row into a table if the row causes a duplicate in UNIQUE index
or PRIMARY KEY , MySQL will issue an error.
Syntax:
If we specify the ON DUPLICATE KEY UPDATE option in the INSERT statement, MySQL
will update the existing row with the new values instead.
Then, query the data from the devices table to verify the insert:
Because there is no duplicate, MySQL inserts a new row into the devices table. The
statement above has the same effect as the following statement:
INSERT INTO mytable (field_1, field_2) VALUES ('data_1', 'data_2'), ('data_1', 'data_3'),
('data_4', 'data_5');
This is an easy way to add several rows at once with one INSERT statement.
This kind of 'batch' insert is much faster than inserting rows one by one. Typically,
inserting 100 rows in a single batch insert this way is 10 times as fast as inserting
them all individually.
However, if you use the INSERT IGNORE statement, the rows with invalid data that
cause the error are ignored and the rows with valid data are inserted into the table.
Let’s execute another statement that inserts two rows into the subscribers table:
INSERT INTO subscribers(email) VALUES('john.doe@gmail.com'),
('jane.smith@ibm.com');
error. Error Code: 1062. Duplicate entry 'john.doe@gmail.com' for key 'email'
As indicated in the error message, the email john.doe@gmail.com violates the
UNIQUE constraint.
If we use the INSERT IGNORE statement instead.
INSERT IGNORE INTO subscribers(email) VALUES('john.doe@gmail.com'),
('jane.smith@ibm.com');
Basic Insert
INSERT INTO subscribers(email)VALUES('john.doe@gmail.com');
For more information on how to set the AUTO_INCREMENT attribute for a column,
check it out the MySQL sequence tutorial.
First, create a new table named tbl for testing. In the tbl table, you set the
AUTO_INCREMENT attribute for the id column.
CREATE TABLE tbl (id INT AUTO_INCREMENT PRIMARY KEY, description VARCHAR(250)
NOT NULL);
Second, insert a new row into the tbl table.
INSERT INTO tbl(description)VALUES('MySQL last_insert_id');
Third, use the MySQL LAST_INSERT_ID function to get the last insert id that MySQL has
been generated.
SELECT LAST_INSERT_ID();
It’s important to note that if you insert multiple rows into a table using a single INSERT
statement, the LAST_INSERT_ID function returns the last insert id of the first row.
Suppose the AUTO_INCREMENT column has current value as 1 and you insert 3 rows
into the table. When you use the LAST_INSERT_ID function to get the last insert id, you
will get 2 instead of 4.
The following statement inserts 3 rows into the tbl table and gets the last insert id
using the LAST_INSERT_ID function.
SELECT LAST_INSERT_ID();
You can SELECT * FROM, but then tableA and tableB must have matching column
count and corresponding datatypes.
The table from which you are going to delete records WHERE conditions. The
conditions that must be met for the records to be deleted.
If no conditions are provided, then all records from the table will be deleted.
ORDER BY expression If ORDER BY is provided, records will be deleted in the given
order LIMIT. It controls the maximum number of records to delete from the table.
Given number_rows will be deleted.
Multi-Table Deletes
MySQL's DELETE statement can use the JOIN construct, allowing also to specify which
tables to delete from. This is useful to avoid nested queries. Given the schema:
create table people ( id int primary key, name varchar(100) not null, gender char(1)
not null );
create table pets ( id int auto_increment primary key, ownerId int not null, name
varchar(100) not null, color varchar(100) not null);
DELETE vs TRUNCATE
The TRUNCATE TABLE statement is used when you want to delete the complete data
from a table without removing the table structure.
Step1:
CREATE TABLE books(id int auto_increment primary key, title varchar(255) not null);
Step 2:
insert into books(title)values('java'),('C++'),('Python');
Step 3:
SELECT * FROM books;
Step 4:
TRUNCATE TABLE books;
Step 5:
SELECT * FROM books;
Multi-table DELETE
MySQL allows to specify from which table the matching rows must be deleted
Step 1:
The following statement deletes the row with id 1 in the t1 table and also row
with ref 1 in the t2 table using DELETE...INNER JOIN statement:
This will delete all rows from the table where the contents of the field_one for that row
match 'value_one'.
The WHERE clause works in the same way as a select, so things like >, <, <> or
LIKE can be used.
delete from items where qty <20;
delete from items where qty >20;
delete from items where qty <> 25;
delete from products where product_name like 'Keyboard';
This will delete everything, all rows from the table. It is the most basic example of the
syntax. It also shows that DELETE statements should really be used with extra care
as they may empty a table, if the WHERE clause is omitted.
LIMITing deletes
DELETE FROM `table_name` WHERE `field_one` = 'value_one' LIMIT 1
delete from items where qty = 25 limit 1;
This works in the same way as the 'Delete with Where clause' example, but it will stop
the deletion once the limited number of rows have been removed.
Chapter 12: UPDATE
Update with Join Pattern
Basic Update
Updating one row
update customers set customer_name = 'Sitaraju' where customer_id = 204;
This query updates the content of email in the customers table to the string luke_smith@email.com where
the value of id is equal to 1. The old and new contents of the database table are illustrated below on the
left and right respectively:
Bulk UPDATE
When updating multiple rows with different values it is much quicker to use a bulk update.
update items set item_name = (CASE item_id when 307 then 'Keyboard' when 310
then 'Mouse' when 315 then 'Monitor'end)where item_id in(307,310,315);
By bulk updating only one query can be sent to the server instead of one query for
each row to update. The cases should contain all possible parameters looked up in the
WHERE clause.
UPDATE tableName
SET column1 = expression1,
column2 = expression2,
...
[WHERE conditions]
[ORDER BY expression [ ASC | DESC ]]
[LIMIT row_count];
INSERT INTO Books VALUES (101, 'Java', 12),(102, 'PHP', 17),(103, 'MySQL', 23),(104,
'Perl', 32),(105, 'Pyton', 6),(106, 'www.java2s.com', 28);
The MySQL ORDER BY clause is used to sort the records in your result set.
Syntax
Parameters or Arguments
Expressions : The columns or calculations that you wish to retrieve.
Tables: The tables that you wish to retrieve records from. There must be
at least one table listed in the FROM clause.
WHERE conditions: Optional. The conditions that must be met for the records to be
selected.
ASC: Optional. It sorts the result set in ascending order
by expression (default, if no modifier is provider).
DESC: Optional. It sorts the result set in descending order
by expression.
Note
If the ASC or DESC modifier is not provided in the ORDER BY clause, the results
will be sorted by expression in ascending order. This is equivalent to ORDER
BY expression ASC.
The ORDER BY clause can be used in a SELECT statement, SELECT LIMIT
statement, and DELETE LIMIT statement in MySQL.
Some tricks
ORDER BY FIND_IN_SET(card_type, "MASTER-CARD,VISA,DISCOVER") -- sort 'MASTER-CARD' first.
ORDER BY x IS NULL, x -- order by `x`, but put `NULLs` last.
Custom ordering
The HAVING clause is used in the SELECT statement to specify filter conditions for a
group of rows or aggregates.
The HAVING clause is often used with the GROUP BY clause to filter groups based on a
specified condition. If you omit the GROUP BY clause, the HAVING clause behaves like
the WHERE clause.
SELECT
select_list
FROM
table_name
WHERE
search_condition
GROUP BY
group_by_expression
HAVING
group_condition;
Using GROUP BY ... HAVING to filter aggregate records for using SELECT ... WHERE
to filter individual records.
A MySQL join is a method of linking data between one or more tables based on values
of the common column between tables.
1. Cross join
2. Inner join
3. Left join
4. Right join
To make easy for you to understand each type of join, we will use the t1 and t2 tables
with the following structures:
CREATE TABLE t1 (id INT PRIMARY KEY, pattern VARCHAR(50) NOT NULL);
CREATE TABLE t2 (id VARCHAR(50) PRIMARY KEY, pattern VARCHAR(50) NOT NULL);
Both t1 and t2 tables have the pattern column, which is also the common column
between tables.
The following statements insert data into both t1 and t2 tables:
INSERT INTO t1(id, pattern) VALUES(1,'Divot'), (2,'Brick'),(3,'Grid');
And the pictures below illustrate data from both t1 and t2 tables:
MySQL CROSS JOIN
Suppose, you join t1 and t2 tables using the CROSS JOIN, the result set will include the
combinations of rows from the t1 table with the rows in the t2 table.
To perform cross join, you use the CROSS JOIN clause as in the following statement:
SELECT t1.id, t2.id FROM t1 CROSS JOIN t2;
The following shows the result set of the query:
As you can see, each row in the t1 table combines with rows in the t2 table to form
the Cartesian product.
The following picture illustrates the CROSS JOIN between t1 and t2 tables.
MySQL INNER JOIN
The following statement uses the INNER JOIN clause to join t1 and t2 tables:
SELECT t1.id, t2.id FROM t1 INNER JOIN t2 ON t1.pattern = t2.pattern;
The following picture illustrates the INNER JOIN between t1 and t2 tables:
In this illustration, the rows in both tables must have the same pattern to be included
in the result set.
MySQL LEFT JOIN
Unlike an INNER JOIN, a LEFT JOIN returns all rows in the left table including rows that
satisfy join-predicate and rows that do not.
For the rows that do not match the join-predicate, NULLs appear in the columns of the
right table in the result set.
The following statement uses the LEFT JOIN clause to join t1 and t2 tables:
SELECT t1.id, t2.id FROM t1 LEFT JOIN t2 ON t1.pattern = t2.pattern ORDER BY
t1.id;
As you can see, all rows in the t1 table are included in the result set. For the rows in
the t1 table (left table) that do not have any matching row in the t2 table (right table),
NULLs are used for columns in t2 table.
The following picture illustrates the LEFT JOIN between t1 and t2 tables:
In this illustration, the following rows share the same pattern: (2 and A), (3 and B).
The row with id 1 in the t1 table has no matching row in the t2 table,
therefore, NULL are used for columns of the t2 table in the result set.
MySQL RIGHT JOIN
A RIGHT JOIN is similar to the LEFT JOIN except that the treatment of tables is
reversed. With a RIGHT JOIN, every row from the right table ( t2) will appear in the
result set. For the rows in the right table that do not have the matching rows in the
left table ( t1), NULLs appear for columns in the left table ( t1).
The following statement joins t1 and t2 tables using RIGHT JOIN:
SELECT t1.id, t2.id FROM t1 RIGHT JOIN t2 on t1.pattern = t2.pattern ORDER BY t2.id;
In this tutorial, you have learned various MySQL join statements including cross join,
inner join, left join and right join to query data from two or more tables.
Chapter 18: UNION
If you needed to keep duplicates in your query, you could use the ALL
keyword like so: UNION ALL.
Combining data with different columns
select supplier_id,supplier_name from suppliers
union
select supplier_id,product_name from products;
When combining 2 record sets with different columns then emulate the missing ones
with default values.
select supplier_id from suppliers union all select supplier_id from orders;
ORDER BY
The MySQL UNION operator can use the ORDER BY clause to order the results of the
query.
( SELECT ... )
UNION
( SELECT ... )
ORDER BY
Combining and merging data on different MySQL tables with the same
columns into unique rows and running query
This UNION ALL combines data from multiple tables and serve as a table name alias
to use for your queries:
DOUBLE
If any numbers in your arithmetic are fractional, MySQL uses 64-bit IEEE 754 floating
point arithmetic. You must be careful when using floating point arithmetic, because
many floating point numbers are, inherently, approximations rather than exact values.
Round up a number
To round up a number use either the CEIL() or CEILING() function
SELECT CEIL(1.23) -> 2
SELECT CEILING(4.83) -> 5
ASCII (str)
In this function returns ASCII code value of the leftmost character of the String str and
returns 0 if str is the empty string.
Returns NULL if str is NULL.
BIT_LENGTH (str)
In the BIT_LENGTH(str) function return the String str length in bits forms.
CHAR_LENGTH(str)
In this function returns String str lengths that is measured in characters. But in this
function a multi-byte character counts as single character such as a string contains 5
two-byte characters, then LENGTH() function returns 10, but the CHAR_LENGTH()
returns 5.
select char_length("ISAN");
CONCAT(str1, str2..)
The CONCAT(str1, str2?.) function can have one or more arguments and its returns a
string that is the result of concatenating the arguments. In this function all arguments
are non-binary strings then the result is also non-binary string but if any argument is
binary string then result is binary string. And a numeric argument is converted to its
equivalent binary string form. But if any argument is NULL then it also returns NULL.
The first argument is treated as a separator for the rest of the arguments and it is
added between the strings for concatenating. If the separator is NULL then the result
is NULL.
FIELD(str,str1,str2,str3,...)
In the FIELD(str,str1,str2,str3,....) function is used to find the index position of str in
the arguments str1,str2,str3.
In other words it returns the index position of str in the arguments. It returns 0 if str is
not available in the arguments. If str is NULL then return value is 0 because NULL fails
equality comparison with any value.
Example: SELECT FIELD ('AA', 'BB', 'AA', 'CC');
FIND_IN_SET(str,strlist)
FIND_IN_SET(str, strlist) function returns a value in the range of 1 to N.
This function find the String str in the substring of String list strlist and return the
index value.
This String list have many substrings that is separated by ?,? characters. This function
returns 0 when str is not available in stringlist or string list is the empty string.
FORMAT(X,D)
In the FORMAT(X,D) function formats the number X like #,###,###.## and rounded
the decimal places to D then returns the string as a result.
HEX(N_or_S)
In HEX(N_or_S) function N_or_S is a number then this function returns a string that is
representation of hexadecimal value of N, where is a longlon(BIGINT) number. But if
N_or_S is a string, then it returns a string hexadecimal representation of N_or_S where
each character in N_or_S is converted to two hexadecimal digits.
Example: SELECT HEX(10);
SELECT HEX( 'abd');
INSERT(str,pos,len,newstr)
This function is used to replace some part or whole String of String str with String
newstr from beginning at position pos and len character long. This function returns
the String str if pos is not within the length of the string. It returns NULL if any
argument is NULL.
INSTR(str,substr)
This function is used to return the position of first occurrence of substr SubString in str
String.
LCASE(str)
The LCASE(str) function is same as LOWER() function
LEFT(str,len)
This function returns the leftmost len characters from the String str.
LENGTH(str)
The LENGTH(str) function returns the length of the String str in bytes.
LOCATE(substr,str), LOCATE(substr,str,pos)
The LOCATE(substr,str) function is same as INSTR(str, substr).
LOCATE(substr,str,pos) function is also same but its just start the to find first
occurrence of substr in String str from position pos.
LPAD(str,len,padstr)
In the LPAD(str, len, padstr) function returns the string str that is left padded with
padstr string for length of len characters. But string str is longer than len characters
then return value is shortend to len characters.
MAKE_SET(bits,str1,str2,...)
The MAKE_SET(bits, str1, str2,..) function is returns a set value consisting of the
strings that have the corresponding bit in bits set. str1 corresponds to bit 0, str2 to bit
1, and so on. NULL values in str1, str2, ... are not appended to the result.
Example:
Select make_set(1, 'apple','mango','grapes');
Select make_set(1|3, 'apple','mango','grapes');
Select make_set(1|4, 'apple','mango','grapes');
MID(str,pos,len)
The MID(str, pos, len) function is same as SUBSTRING(str,pos,len)
Example:
REVERSE(str)
The REVERSE(str) function is used to return the reverse of String str.
RTRIM(str)
The RTRIM(str) function returns the String str with trailing space characters removed.
SUBSTRING(str,pos):
SUBSTRING (or equivalent: SUBSTR) returns the substring starting from the specified
position and, optionally, with the specified length
Syntax: SUBSTRING(str, start_position)
MySQL DATE is one of the five temporal data types used for managing date values.
MySQL uses yyyy-mm-dd format for storing a date value. This format is fixed and it is
not possible to change it.
For example, we may prefer to use mm-dd-yyyy format but you can’t. Instead, you
follow the standard date format and use the DATE_FORMAT function to format the
date the way you want.
MySQL uses 3 bytes to store a DATE value. The DATE values range from 1000-01-
01 to 9999-12-31. If you want to store a date value that is out of this range, you need
to use a non-temporal data type like integer e.g., three columns, and each column for
the year, month, and day. You also need to create stored functions to simulate the
built-in date functions provided by MySQL, which is not recommended.
When strict mode is disabled, MySQL converts any invalid date e.g., 2015-02-30 to the
zero date value 0000-00-00.
MySQL Date values with two-digit years
MySQL stores the year of the date value using four digits. In case you use two-digit
year values, MySQL still accepts them with the following rules:
First, create a table named people with birth date column with DATE data type.
CREATE TABLE people (id INT AUTO_INCREMENT PRIMARY KEY,first_name
VARCHAR(50) NOT NULL,last_name VARCHAR(50) NOT NULL,birth_date DATE NOT
NULL);
After that, use the two-digit year format to insert data into the people table.
INSERT INTO people(first_name,last_name,birth_date)VALUES('Jack','Daniel','01-09-
01'),('Lily','Bush','80-09-01');
In the first row, we used 01 (range 00-69) as the year, so MySQL converted it to 2001.
In the second row, we used 80 (range 70-99) as the year, MySQL converted it to 1980.
Finally, we can query data from the people table to check whether data was
converted based on the conversion rules.
SELECT first_name, last_name, birth_date FROM people;
To get the current date and time, you use NOW() function.
SELECT NOW();
+---------------------+
| NOW() |
+---------------------+
| 2017-05-13 07:59:38 |
+---------------------+
1 row in set (0.02 sec)
To get only date part of a DATETIME value, you use the DATE() function.
SELECT DATE(NOW());
+-------------+
| DATE(NOW()) |
+-------------+
| 2015-07-13 |
+-------------+
1 row in set (0.01 sec)
In this example, we used the SLEEP() function to pause the query for 5 seconds.
SELECT NOW(), SLEEP(5), NOW();
To get the current system date, you use CURDATE() function as follows:
SELECT CURDATE();
+------------+
| CURDATE() |
+------------+
| 2015-07-13 |
+------------+
1 row in set (0.02 sec)
The SYSDATE() function returns the current date and time as a value in 'YYYY-MM-DD
HH:MM:SS' format if the function is used in a string context
or YYYYMMDDHHMMSS format in case the function is used in a numeric context.
The SYSDATE() function accepts an optional argument fsp that determines whether
the result should include a fractional seconds precision which ranges from 0 to 6.
See the following example.
SELECT SYSDATE();
+---------------------+
| SYSDATE() |
+---------------------+
| 2019-03-09 10:36:56 |
+---------------------+
1 row in set (0.00 sec)
If you pass the fsp argument, the result will include the fractional seconds precision as
shown in the following example:
SELECT SYSDATE(3);
+-------------------------+
| SYSDATE(3) |
+-------------------------+
| 2019-03-09 10:38:11.070 |
+-------------------------+
1 row in set (0.00 sec)
To format a date value, you use DATE_FORMAT function. The following statement
formats the date as mm/dd/yyyy using the date format pattern %m/%d/%Y :
SELECT DATE_FORMAT(CURDATE(), '%m/%d/%Y') today;
+------------+
| today |
+------------+
| 07/13/2015 |
+------------+
1 row in set (0.02 sec)
To calculate the number of days between two date values, you use the DATEDIFF
function as follows:
SELECT DATEDIFF('2015-11-04','2014-11-04') days;
+------+
| days |
+------+
| 365 |
+------+
1 row in set (0.02 sec)
To add a number of days, weeks, months, years, etc., to a date value, you use
the DATE_ADD function:
Similarly, you can subtract an interval from a date using the DATE_SUB function:
To get the week information week related functions. For example, WEEK function
returns the week number, WEEKDAY function returns the weekday index,
and WEEKOFYEAR function returns the calendar week.
+---------+------+------------+
| weekday | week | weekofyear |
+---------+------+------------+
| 6 | 53 | 52 |
+---------+------+------------+
1 row in set (0.04 sec)
The week function returns the week number with the zero-based index if you don’t
pass the second argument or if you pass 0. If you pass 1, it will return week number
with 1-indexed.
SELECT @@system_time_zone;
SELECT @@GLOBAL.time_zone, @@SESSION.time_zone;
SELECT @@time_zone;
dt A datetime.
from_tz A time zone which will be converted to to_tz.
to_tz A time zone in which the from_tz will convert.
The MySQL TIMESTAMP is a temporal data type that holds the combination of date
and time. The format of a TIMESTAMP is YYYY-MM-DD HH:MM:SS which is fixed at 19
characters. The TIMESTAMP value has a range from '1970-01-01 00:00:01' UTC to
'2038-01-19 03:14:07' UTC
Unfortunately, that usually yields the value SYSTEM, meaning the MySQL time is
governed by the server OS's time zone setting.
Pattern ^
Select all emp whose FIRST_NAME starts with N.
Query
SELECT * FROM emp WHERE FIRST_NAME REGEXP '^N'
-- Pattern start with----------------------------^
Pattern $**
Select all emp whose PHONE_NUMBER ends with 4569.
Query
SELECT * FROM emp WHERE mobile REGEXP '4569$'
-- Pattern end with----------------------------------^
NOT REGEXP
Select all emp whose FIRST_NAME does not start with N.
Query
SELECT * FROM emp WHERE FIRST_NAME NOT REGEXP '^N'
-- Pattern does not start with---------------^
Regex Contain
Select all emp whose LAST_NAME contains in and whose FIRST_NAME contains a.
Query
SELECT * FROM emp WHERE FIRST_NAME REGEXP 'a' AND LAST_NAME REGEXP 'in'
Pattern or |
Select all emp whose FIRST_NAME starts with A or B or C and ends with r, e, or i.
Query
SELECT * FROM emp WHERE FIRST_NAME REGEXP '^[ABC]|[rei]$'
Counting regular expression matches
Consider the following query:
SELECT FIRST_NAME, IF(FIRST_NAME REGEXP '^N', 'matches ^N', 'does not match
^N') as matching FROM emp;
Within a database, base tables and views share the same namespace, so a base table
and a view cannot have the same name.
A VIEW can: be created from many kinds of SELECT statements refer to base tables or
other views use joins, UNION, and subqueries SELECT need not even refer to any
tables
Another Example
The following example defines a view that selects two columns from another table as
well as an expression calculated from those columns:
select * from v;
DROPPING A VIEW
-- Create and drop a view in the current database.
CREATE VIEW few_rows_from_t1 AS SELECT * FROM t1 LIMIT 10;
DROP VIEW few_rows_from_t1;
Things like GROUP BY, UNION, HAVING, DISTINCT, and some subqueries prevent
the view from being updatable.
Chapter 25: Table Creation
Table creation with Primary Key
CREATE TABLE Person (PersonID INT UNSIGNED NOT NULL,LastName VARCHAR(66)
NOT NULL,FirstName VARCHAR(66),Address VARCHAR(255),City VARCHAR(66),
PRIMARY KEY (PersonID));
A table can have only one PRIMARY KEY, and each table is recommended to have
one. InnoDB will automatically create one in its absence, (as seen in MySQL
documentation) though this is less desirable.
Often, an AUTO_INCREMENT INT also known as "surrogate key", is used for thin
index optimization and relations with other tables. This value will (normally) increase
by 1 whenever a new record is added, starting from a default value of 1.
However, despite its name, it is not its purpose to guarantee that values are
incremental, merely that they are sequential and unique.
An auto-increment INT value will not reset to its default start value if all rows in the
table are deleted, unless the table is truncated using TRUNCATE TABLE statement.
CREATE TABLE Person ( PersonID INT UNSIGNED NOT NULL PRIMARY KEY,
LastName VARCHAR(66) NOT NULL, FirstName VARCHAR(66), Address
VARCHAR(255), City VARCHAR(66));
3. Attributes NULL | NOT NULL: If NOT NULL is specified, then any attempt to store
a NULL value in that field will fail.
Setting defaults
Additionally, where it makes sense you can set a default value for each field by using
DEFAULT:
If during inserts no Street is specified, that field will be NULL when retrieved. When
no Country is specified upon insert, it will default to "United States".
You can set default values for all column types, except for BLOB, TEXT, GEOMETRY,
and JSON fields.
Foreign key: A Foreign Key (FK) is either a single column, or multi-column composite
of columns, in a referencing table. This FK is confirmed to exist in the referenced
table. It is highly recommended that the referenced table key
confirming the FK be a Primary Key, but that is not enforced. It is used as a fast-
lookup into the referenced where it does not need to be unique, and in fact can be a
left-most index there.
MySQL creating table foreign key example
Syntax:
ALTER table_name
ADD CONSTRAINT constraint_name
FOREIGN KEY foreign_key_name(columns)
REFERENCES parent_table(columns)
ON DELETE action
ON UPDATE action;
CREATE TABLE vendors(vdr_id int not null auto_increment primary key, vdr_name
varchar(255));
ALTER TABLE prod ADD COLUMN vdr_id int not null AFTER cat_id;
To add a foreign key to the products table, you use the following statement:
ALTER TABLE prod ADD FOREIGN KEY fk_vendor(vdr_id) REFERENCES vendors(vdr_id)
ON DELETE RESTRICT ON UPDATE CASCADE;
First, you specify the table name from which you want to remove the foreign key.
Second, you put the constraint name after the DROP FOREIGN KEY clause.
CONSTRAINT products_ibfk_2
FOREIGN KEY (vdr_id)
REFERENCES vendors (vdr_id)
ON DELETE NO ACTION
ON UPDATE CASCADE,
CONSTRAINT products_ibfk_1
FOREIGN KEY (cat_id)
REFERENCES categories (cat_id)
ON UPDATE CASCADE
);
To change the type of age column from char to int, we use the query below:
ALTER TABLE users CHANGE age ages tinyint UNSIGNED NOT NULL;
To lock a table, you specify its name after the LOCK TABLES keywords. In addition,
you specify the type of lock, either READ or WRITE.
To release a lock for a table, you use the following statement:
UNLOCK TABLES;
Read Locks
A READ lock has the following features:
A READ lock for a table can be acquired by multiple sessions at the same time.
In addition, other sessions can read data from the table without acquiring the
lock.
The session that holds the READ lock can only read data from the table, but
cannot write. In addition, other sessions cannot write data to the table until
the READ lock is released. The write operations from another session will be put
into the waiting states until the READ lock is released.
If the session is terminated, either normally or abnormally, MySQL will release
all the locks implicitly. This feature is also relevant for the WRITE lock.
Let’s take a look at how the READ lock works in the following scenario.
In the first session, first, connect to the sampledb database and use
the CONNECTION_ID() function to get the current connection id as follows:
SELECT CONNECTION_ID();
The only session that holds the lock of a table can read and write data from the
table.
Other sessions cannot read data from and write data to the table until
the WRITE lock is released.
Its working.
Next, read data from the tbl table.
MySQL puts these operations into a waiting state. You can check it using the SHOW
PROCESSLIST statement.
SHOW PROCESSLIST
UNLOCK TABLES;
You will see all pending operations from the second session executed and the
following picture illustrates the result:
Chapter 30: Stored routines (procedures
and functions)
A stored procedure is a segment of declarative SQL statements stored inside the
database catalog. A stored procedure can be invoked by triggers, other stored
procedures, and applications such as Java, Python, PHP.
A stored procedure that calls itself is known as a recursive stored procedure. Most
database management systems support recursive stored procedures. However,
MySQL does not support it very well. You should check your version of MySQL
database before implementing recursive stored procedures in MySQL.
MySQL is known as the most popular open source RDBMS which is widely used by
both community and enterprise. However, during the first decade of its existence, it
did not support stored procedures, stored functions, triggers, and events. Since
MySQL version 5.0, those features were added to the MySQL database engine to make
it more flexible and powerful.
Almost stored procedures that you develop require parameters. The parameters make
the stored procedure more flexible and useful. In MySQL, a parameter has one of
three modes: IN,OUT, or INOUT.
IN – is the default mode. When you define an IN parameter in a stored procedure, the
calling program has to pass an argument to the stored procedure. In addition, the
value of an IN parameter is protected. It means that even the value of
the IN parameter is changed inside the stored procedure, its original value is retained
after the stored procedure ends. In other words, the stored procedure only works on
the copy of the IN parameter.
The IN parameter example
DELIMITER //
CREATE PROCEDURE Getitem2(IN sup_id int)
BEGIN
SELECT * FROM items WHERE supplier_id = sup_id;
END //
DELIMITER ;
call Getitem1(101);
We did this to tell MySQL to use a different delimiter while it creates our stored
procedure.
The reason for this is that, MySQL already recognizes the semicolon as a delimiter for
marking the end of each SQL statement. Therefore, as soon as MySQL sees the first
semicolon, it will interpret the delimiter as such and our stored procedure would
break.
The DELIMITER command allows us to tell MySQL to use a different delimiter. In the
above example we set this to two forward slashes (//) but this could've been anything
(although, avoid using a backslash (\) as that is the escape character for MySQL). By
changing the delimiter, MySQL won't try to interpret our semicolons as the end of the
statement — it will wait until it sees the two forward slashes.
Once we've created the stored procedure, we can use DELIMITER ; to reset the
delimiter back to the semicolon.
OUT – the value of an OUT parameter can be changed inside the stored procedure and
its new value is passed back to the calling program. Notice that the stored procedure
cannot access the initial value of the OUT parameter when it starts.
The following stored procedure returns the number of orders by order status. It has
two parameters:
i_name : the IN parameter that is to read item_name from the items tabless.
total : the OUT parameter that stores the number of items int items table.
DELIMITER $$
CREATE PROCEDURE itemCount1(IN i_name VARCHAR(25), OUT total INT)
BEGIN
SELECT count(item_name) INTO total FROM items WHERE item_name = i_name;
END$$
DELIMITER ;
call itemCount1('Keyboard',@total);
select @total;
INOUT – an INOUT parameter is a combination of IN and OUT parameters. It means
that the calling program may pass the argument, and the stored procedure can
modify the INOUT parameter, and pass the new value back to the calling program.
DELIMITER //
CREATE PROCEDURE set_counter3(INOUT count INT(4),IN inc INT(4))
BEGIN
SET count = count + inc;
END$$;
DELIMITER;
mysql> DELIMITER ;
mysql> SET @counter = 1;
Query OK, 0 rows affected (0.00 sec)
CALL spcheck(101);
The WHILE loop checks the expression at the beginning of each iteration. If the
expression valuates to TRUE, MySQL will execute statements between WHILE and END
WHILE until the expression evaluates to FALSE. The WHILE loop is called pretest loop
because it checks the expression before the statements execute.
DELIMITER $$
DROP PROCEDURE IF EXISTS test_mysql_while_loop$$
CREATE PROCEDURE test_mysql_while_loop()
BEGIN
DECLARE x INT;
DECLARE str VARCHAR(255);
SET x = 1;
SET str = '';
WHILE x <= 5 DO
SET str = CONCAT(str,x,',');
SET x = x + 1;
END WHILE;
SELECT str;
END$$
DELIMITER ;
First, we build str string repeatedly until the value of the x variable is greater than 5.
Then, we display the final string using the SELECT statement.
Notice that if we don’t initialize the xvariable, its default value is NULL. Therefore, the
condition in the WHILEloop statement is always TRUE and you will have an indefinite
loop, which is not expected.
CALL test_mysql_while_loop();
REPEAT loop
The syntax of the REPEAT loop statement is as follows:
REPEAT
statements;
UNTIL expression
END REPEAT
First, MySQL executes the statements, and then it evaluates the expression. If the
expression valuates to FALSE, MySQL executes the statements repeatedly until the
expression evaluates to TRUE.
Because the REPEAT loop statement checks the expression after the execution of
statements, the REPEAT loop statement is also known as the post-test loop.
DELIMITER $$
DROP PROCEDURE IF EXISTS mysql_test_repeat_loop$$
CREATE PROCEDURE mysql_test_repeat_loop()
BEGIN
DECLARE x INT;
DECLARE str VARCHAR(255);
SET x = 1;
SET str = '';
REPEAT
SET str = CONCAT(str,x,',');
SET x = x + 1;
UNTIL x > 5
END REPEAT;
SELECT str;
END$$
DELIMITER ;
CALL mysql_test_repeat_loop();
DROP PROCEDURE
Syntax
DROP PROCEDURE [IF EXISTS] sp_name
BEGIN
declaration_section
executable_section
END;
DELIMITER |
BEGIN
DECLARE olditem VARCHAR(20);
SELECT item_name into olditem FROM items where item_id = itm_Id;
UPDATE items SET item_name = newitem where item_id = itm_Id;
RETURN olditem;
END
|
DELIMITER ;
Execute as follows:
mysql> SELECT hello_world('Earth');
Output:
SELECT hello_world('Earth');
SET v_total = 0;
count_loop: LOOP
SET v_total = v_total + 1;
IF v_total = 10 THEN
LEAVE count_loop;
END IF;
END LOOP;
RETURN v_total;
END;
$$
DELIMITER ;
Output:
select looptest();
Introduction to MySQL cursor. To handle a result set inside a stored procedure, you
use a cursor. A cursor allows you to iterate a set of rows returned by a query and
process each row accordingly. MySQL cursor is read-only, non-scrollable and a
sensitive.
Syntax
The syntax to declare a cursor in MySQL is:
Parameters or Arguments
cursor_name
The name to assign to the cursor.
select_statement
The SELECT statement associated with the cursor.
Example:
DECLARE c1 CURSOR FOR
SELECT item_id FROM items WHERE item_name = name_in;
DELIMITER //
BEGIN
OPEN c1;
FETCH c1 INTO itemID;
CLOSE c1;
RETURN itemID;
END; //
DELIMITER ;
CREATE TABLE t(c1 INT PRIMARY KEY, c2 INT NOT NULL,c3 INT NOT NULL, c4
VARCHAR(10), INDEX (c2,c3));
To add an index for a column or a set of columns, you use the CREATE
INDEX statement as follows:
To create an index for a column or a list of columns, you specify the index name, the
table to which the index belongs, and the column list.
For example, to add a new index for the column c4, you use the following statement:
Drop index
-- Drop an index for column 'name' in table 'my_table'
DROP INDEX idx_name ON my_table;
Performance: MySQL has to scan the whole table to find the exact text based on a
pattern in the LIKE statement or pattern in the regular expressions.
Flexible search: with the LIKE operator and regular expression searches, it is
difficult to have a flexible search query e.g., to find product whose description
contains car but not classic.
Relevance ranking: there is no way to specify which row in the result set is
more relevant to the search terms.
Because of these limitations, MySQL extended a very nice feature so-called full-text
search. Technically, MySQL creates an index from the words of the enabled full-text
search columns and performs searches on this index. MySQL uses a sophisticated
algorithm to determine the rows matched against the search query.
Typically, you define the FULLTEXT index for a column when you create a new table
using the CREATE TABLE statement as follows:
CREATE TABLE posts (id int(4) NOT NULL AUTO_INCREMENT, title varchar(255) NOT
NULL,post_content text, PRIMARY KEY (id), FULLTEXT KEY post_content
(post_content));
In case you already have existing tables and want to define full-text indexes, you can
use the ALTER TABLE statement or CREATE INDEX statement.
The following syntax defines a FULLTEXT index using the ALTER TABLE statement:
ALTER TABLE table_name ADD FULLTEXT(column_name1, column_name2,…)
In this syntax, you put the table_name and the ADD FULLTEXT clause that defines
a FULLTEXT index for one or more columns.
For example, you can define a FULLTEXT index for the product_name column in
the products table as follows:
ALTER TABLE products ADD FULLTEXT(product_name);
The following statement creates a FULLTEXT index for the post_content column of
the posts table.
Notice that for a table which has many rows, it is faster to load the data into the table
that has no FULLTEXT index first and then create the FULLTEXT index, than loading a
large amount of data into a table that has an existing FULLTEXT index.
To remove a FULLTEXT index, you just delete the index using the ALTER TABLE …
DROP INDEX statement. For example, the following statement removes
the address FULLTEXT index in the offices table:
Prior MySQL version 4.1, the query is sent to the MySQL server in the textual format.
In turn, MySQL returns the data to the client using textual protocol. MySQL has
to fully parse the query and transforms the result set into a string before returning it
to the client.
The textual protocol has serious performance implication. To resolve this problem,
MySQL added a new feature called prepared statement since version 4.1.
When MySQL executes this query with different productcode values, it does not have
to parse the query fully. As a result, this helps MySQL execute the query faster,
especially when MySQL executes the query multiple times. Because the prepared
statement uses placeholders (?), this helps avoid many variants of SQL injection
hence make your application more secure.
In order to use MySQL prepared statement, you need to use other three MySQL
statements as follows:
DELIMITER $$
create procedure tbl_del6(tab_name varchar(40))
BEGIN
SET @A:= CONCAT('Select * from',' ',tab_name);
prepare stmt FROM @A;
EXECUTE stmt;
END $$
DELIMITER;
Calling procedures
CALL tbl_del4('students');
Output:
mysql> CALL tbl_del4('students');
+------+------+
| Id | Name |
+------+------+
| 1 | Sow |
| 2 | Ram |
| 3 | Sat |
+------+------+
3 rows in set (0.02 sec)
Chapter 34: MySQL Admin
Section 36.1: Atomic RENAME & Table Reload
RENAME TABLE t TO t_old, t_copy TO t;
No other sessions can access the tables involved while RENAME TABLE executes, so the rename
operation is not subject to concurrency problems.
Atomic Rename is especially for completely reloading a table without waiting for DELETE and load to
finish:
CREATE TABLE new LIKE real;
load `new` by whatever means - LOAD DATA, INSERT, whatever
RENAME TABLE real TO old, new TO real;
DROP TABLE old;
View table:-
select * from employee;
Create table:-
Now Create another table 'Employee_log' with field name and data type respectively.
CREATE TABLE Employee_log(user_id VARCHAR(15), description VARCHAR(100));
View table:-
select * from employee_log;
Create Trigger:-
The Create Trigger create a Employee_Trigger on table 'employee'. The Trigger
'Employee_Trigger' fired automatically after update operation is performed on table
'employee'. Further,the update records is inserted on table 'Employee_log'.
delimiter $$
CREATE TRIGGER Employee_Trigger
AFTER UPDATE ON employee
FOR EACH ROW
BEGIN
INSERT into Employee_log
(user_id, description)VALUES (user(),
CONCAT('Id with ',NEW.id,' is modified ',
' from ',OLD.start_date, ' to ', NEW.start_date));
END$$
delimiter ;
Table that has been modified after update query executes is Employee_log:-
Query to view Employee_log table:-
select * from Employee_log;
+----------------+------------------------------------------------------+
| user_id | description |
+----------------+------------------------------------------------------+
| root@localhost | Id with 1 is modified from 2008-12-25 to 2006-12-31 |
| root@localhost | Id with 2 is modified from 2007-11-22 to 2006-12-31 |
| root@localhost | Id with 3 is modified from 2006-10-12 to 2006-12-31 |
+----------------+------------------------------------------------------+
Trigger in Mysql fired trigger automatically after you perform Delete Operation on
Table.
Create table:-
drop table Employee;
CREATE TABLE Employee(id int, first_name VARCHAR(30), last_name VARCHAR(15),
start_date DATE, end_date DATE, city VARCHAR(10), description VARCHAR(15));
View table:-
To view table employee, we use select keyword that show you the entire records
from table 'employee'.
select * from employee;
Create table:-
Now we include another table 'Employee_log'. The create tableconstruct another
table Employee_log.
drop table Employee_log;
CREATE TABLE Employee_log(id int, first_name varchar(50), last_name varchar(50),
start_date date, end_date date, city varchar(50),description varchar(50),Lasinserted
Time);
View table:-
Again, we use same select Query to return the records from a table employee_log.
select * from employee_log;
Create Trigger:-
Drop Trigger is used to delete trigger Employee_Trigger from database, in case if
there is any trigger existing on this name. The 'Employee_Triger' fired trigger after
you perform a delete operation on table 'employee'. The deleted records from table
'employee' copy into a table 'employee_log'.
drop trigger if exists Employee_Trigger;
delimiter $$
CREATE TRIGGER Employee_Trigger
AFTER delete ON employee
FOR EACH ROW
BEGIN
insert into employee_log values(old.id,old.first_name,
old.last_name,old.start_date,old.end_date,
old.city,old.description,curtime());
END$$
delimiter ;
Table that has been modified after delete query executes is Employee_log:-
Query to view Employee_log table:-
select * from employee_log;
The Tutorial illustrate an example from Mysql Trigger After Insert. To understand this,
we create a table 'Employee'. The create table is used to construct a table 'Employee'.
Create table:-
drop table Employee;
CREATE TABLE Employee(id int, first_name VARCHAR(30),last_name
VARCHAR(15),start_date DATE, end_date DATE, city VARCHAR(10), description
VARCHAR(15));
View table:-
To view a table employee we use select query that return the records from a table
'employee'.
Create table:-
The create table construct a table Employee_log.
drop table Employee_log;
CREATE TABLE Employee_log(id int,first_name varchar(50),last_name varchar(50),
start_date date,end_date date,city varchar(50),description varchar(50),Lasinserted
Time);
View table:-
select * from employee_log;
Create Trigger:-
The Create Trigger create a trigger 'Employee_Trigger' on table 'employee'. The 'After
insert trigger' fired the trigger after you performed a insert operation on table.
delimiter $$
CREATE TRIGGER Employee_Trigger
AFTER insert ON employee
FOR EACH ROW
BEGIN
insert into employee_log values(new.id,new.first_name,
new.last_name,new.start_date,new.end_date,
new.city,new.description,curtime());
END$$
delimiter ;
The insert into add the records or rows into the table 'employee'.
insert into employee values
(4,'Amit','Kumar','20081225','20101203','Lucknow','Programmer');
Table that has been modified after update query executes is Employee_log:-
select * from employee_log;
delimiter //
CREATE TRIGGER agecheck BEFORE INSERT ON people FOR EACH ROW IF NEW.age <
0 THEN SET NEW.age = 0; END IF;//
delimiter ;
Description
A BEFORE UPDATE Trigger means that MySQL will fire this trigger before the UPDATE
operation is executed.
Syntax
The syntax to create a BEFORE UPDATE Trigger in MySQL is:
BEGIN
-- variable declarations
-- trigger code
END;
Parameters or Arguments
trigger_name : The name of the trigger to create.
BEFORE UPDATE : It indicates that the trigger will fire before the UPDATE operation
is executed.
table_name: The name of the table that the trigger is created on.
Restrictions
You can not create a BEFORE trigger on a view.
You can update the NEW values.
You can not update the OLD values.
Note
See also how to create AFTER DELETE, AFTER INSERT, AFTER UPDATE, BEFORE
DELETE, and BEFORE INSERT triggers.
Example
Let's look at an example of how to create an BEFORE UPDATE trigger using the
CREATE TRIGGER statement in MySQL.
insert into
contacts(last_name,first_name,birthday,created_date,created_by)values('M','sou','198
61002','19801014','Kamesh');
We could then use the CREATE TRIGGER statement to create an BEFORE UPDATE
trigger as follows:
DELIMITER //
BEGIN
DELIMITER ;
update contacts set last_name = 'N' where last_name = 'M';
Description
A BEFORE DELETE Trigger means that MySQL will fire this trigger before the DELETE
operation is executed.
Syntax
The syntax to create a BEFORE DELETE Trigger in MySQL is:
BEGIN
-- variable declarations
-- trigger code
END;
Parameters or Arguments
trigger_name : The name of the trigger to create.
BEFORE DELETE: It ndicates that the trigger will fire before the DELETE operation is
executed.
table_name: The name of the table that the trigger is created on.
Restrictions
You can not create a BEFORE trigger on a view.
You can update the NEW values.
You can not update the OLD values.
Note
See also how to create AFTER DELETE, AFTER INSERT, AFTER UPDATE, BEFORE
INSERT, and BEFORE UPDATE triggers.
Example
Let's look at an example of how to create an BEFORE DELETE trigger using the
CREATE TRIGGER statement in MySQL.
We could then use the CREATE TRIGGER statement to create an BEFORE DELETE
trigger as follows:
DELIMITER //
BEGIN
END; //
DELIMITER ;
Chapter 36: Events
Working with MySQL Scheduled Event
A MySQL event is a task that runs based on a predefined schedule therefore
sometimes it is referred to as a scheduled event. MySQL event is also known as
“temporal trigger” because it is triggered by time, not by table update like a trigger. A
MySQL event is similar to a cron job in UNIX or a task scheduler in Windows.
You can use MySQL events in many cases such as optimizing database tables,
cleaning up logs, archiving data, or generate complex reports during off-peak time.
MySQL uses a special thread called event schedule thread to execute all scheduled
events. You can see the status of event scheduler thread by executing the following
command:
SHOW PROCESSLIST;
By default, the event scheduler thread is not enabled. To enable and start the event
scheduler thread, you need to execute the following command:
Now to see the status of event scheduler thread, you execute the SHOW
PROCESSLIST command again.
To disable and stop the event the event scheduler thread, you execute the SET
GLOBAL command with value of the event_scheduler is OFF:
To create and schedule a new event, you use the CREATE EVENT statement as
follows:
CREATE EVENT [IF NOT EXIST] event_name
ON SCHEDULE schedule
DO
event_body
This event makes the MySQL server drop a table exactly 5 days from now:
Example:
CREATE EVENT 'My event' ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 5 DAY
DO DROP TABLE t;
This event makes the MySQL server drop a table on February 24, 2018 at exactly 12
o'clock:
CREATE EVENT The_Main_Event
ON SCHEDULE AT TIMESTAMP '2018-02-24 12:00:00'
DO DROP TABLE t;
EVERY interval means "Do this repeatedly". A recurring interval starts with EVERY,
followed by a positive integer plus an INTERVAL interval, as we saw in the last blog.
For example, this event makes MySQL drop table t once each year, starting now:
CREATE EVENT e ON SCHEDULE EVERY 1 YEAR DO DROP TABLE t;
This event would cause MySQL to drop a table once each year for five years, starting
exactly 2 days from now:
CREATE EVENT e
ON SCHEDULE EVERY 1 YEAR
STARTS CURRENT_TIMESTAMP + INTERVAL 2 DAY
ENDS CURRENT_TIMESTAMP + INTERVAL 5 YEAR
DO DROP TABLE t;
First, you specify the event name after the CREATE EVENT clause. The event
name must be unique within a database schema.
Second, you put a schedule after the ON SCHEDULE clause. If the event is a one-
time event, you use the syntax: AT timestamp [+ INTERVAL] If the event is a
recurring event, you use the EVERY clause: EVERY interval STARTS timestamp
[+INTERVAL] ENDS timestamp [+INTERVAL]
Third, you place the SQL statements after the DO keyword. It is important to
notice that you can call a stored procedure inside the body of the event. In case
you have compound SQL statements, you can wrap them in a BEGIN END block.
Let’s look at few examples of creating events to understand the syntax above.
To create and schedule a new one-time event that inserts a message into a table
called messages you do the following steps:.
First, create a new table named messages by using the CREATE TABLE statement as
follows:
Third, check the messages table; you will see that we have 1 record. It means the
event was executed when it is created.
To shows all events of a database schema, you use the following statement:
We don’t see any row returned because an event is automatically dropped when it is
expired. In our case, it is a one-time event and expired when its execution completed.
To change this behavior, you can use the ON COMPLETION PRESERVE clause. The
following statement creates another one-time event that is executed after its creation
time 1 minute and not dropped after execution.
Wait for 1 minute, check the messages table, another record was added:
SELECT * FROM messages;
If we execute the SHOW EVENTS statement again, we see the event is there because
the effect of the ON COMPLETION PRESERVE clause:
Notice that we used STARTS and ENDS clauses to define expiration period for the
event. You can test this recurring event by waiting for few minutes and check
the messages table.
For example, to drop the test_event_03 event, you use the following statement:
Clustered
o Clustered indexes sort and store the data rows in the table or view based on
their key values. These are the columns included in the index definition. There
can be only one clustered index per table, because the data rows themselves
can be stored in only one order.
o The only time the data rows in a table are stored in sorted order is when the
table contains a clustered index. When a table has a clustered index, the table
is called a clustered table. If a table has no clustered index, its data rows are
stored in an unordered structure called a heap.
Nonclustered
o The pointer from an index row in a nonclustered index to a data row is called a
row locator. The structure of the row locator depends on whether the data
pages are stored in a heap or a clustered table. For a heap, a row locator is a
pointer to the row. For a clustered table, the row locator is the clustered index
key.
o You can add nonkey columns to the leaf level of the nonclustered index to by-
pass existing index key limits, and execute fully covered, indexed, queries. For
more information, see Create Indexes with Included Columns. For details about
index key limits see Maximum Capacity Specifications for SQL Server.
Both clustered and nonclustered indexes can be unique. This means no two rows can
have the same value for the index key. Otherwise, the index is not unique and
multiple rows can share the same key value. For more information, see Create Unique
Indexes.
Indexes are automatically maintained for a table or view whenever the table data is
modified.
Indexes and Constraints
Indexes are automatically created when PRIMARY KEY and UNIQUE constraints are
defined on table columns. For example, when you create a table with a UNIQUE
constraint, Database Engine automatically creates a non-clustered index. If you
configure a PRIMARY KEY, Database Engine automatically creates a clustered index,
unless a clustered index already exists. When you try to enforce a PRIMARY KEY
constraint on an existing table and a clustered index already exists on that table, SQL
Server enforces the primary key using a nonclustered index.
Chapter 39: Partitioning
MySQL partitioning is about altering – ideally, optimizing – the way the database
engine physically stores data. It allows you to distribute portions of table data (a.k.a.
partitions) across the file system based on a set of user-defined rules (a.k.a. the
“partitioning function”).
RANGE Partitioning
LIST Partitioning
COLUMNS Partitioning
HASH Partitioning
KEY Partitioning
Subpartitioning
How MySQL Partitioning Handles NULL
The types of partitioning which are available in MySQL 5.5. These include the types
listed here:
Example:
drop table employees;
CREATE TABLE employees (id INT NOT NULL,fname VARCHAR(30),lname
VARCHAR(30),hired DATE NOT NULL DEFAULT '1970-01-01', separated DATE NOT
NULL DEFAULT '9999-12-31', job_code INT NOT NULL,store_id INT NOT NULL);
This table can be partitioned by range in a number of ways, depending on your needs.
One way would be to use the store_id column. For instance, you might decide to
partition the table 4 ways by adding a PARTITION BY RANGE clause as shown here:
drop table employee;
CREATE TABLE employees (
id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT '1970-01-01',
separated DATE NOT NULL DEFAULT '9999-12-31',
job_code INT NOT NULL,
store_id INT NOT NULL
)
PARTITION BY RANGE (store_id) (
PARTITION p0 VALUES LESS THAN (6),
PARTITION p1 VALUES LESS THAN (11),
PARTITION p2 VALUES LESS THAN (16),
PARTITION p3 VALUES LESS THAN (21)
);
In this partitioning scheme, all rows corresponding to employees working at stores 1
through 5 are stored in partition p0, to those employed at stores 6 through 10 are
stored in partition p1, and so on. Note that each partition is defined in order, from
lowest to highest.
MAXVALUE represents an integer value that is always greater than the largest
possible integer value (in mathematical language, it serves as a least upper bound).
Now, any rows whose store_id column value is greater than or equal to 16 (the
highest value defined) are stored in partition p3. At some point in the future—when
the number of stores has increased to 25, 30, or more
Regio Store ID
n Numbers
North 3, 5, 6, 9, 17
1, 2, 10, 11, 19,
East 20
4, 12, 13, 14,
West 18
Centr
al 7, 8, 15, 16
To partition this table in such a way that rows for stores belonging to the same region
are stored in the same partition, you could use the CREATE TABLE statement shown
here:
CREATE TABLE employees (
id INT NOT NULL,
fname VARCHAR(30),
lname VARCHAR(30),
hired DATE NOT NULL DEFAULT '1970-01-01',
separated DATE NOT NULL DEFAULT '9999-12-31',
job_code INT,
store_id INT
)
PARTITION BY LIST(store_id) (
PARTITION pNorth VALUES IN (3,5,6,9,17),
PARTITION pEast VALUES IN (1,2,10,11,19,20),
PARTITION pWest VALUES IN (4,12,13,14,18),
PARTITION pCentral VALUES IN (7,8,15,16)
);
TRUNCATE h2;
SELECT * FROM h2;
INSERT IGNORE INTO h2 VALUES (2, 5), (6, 10), (7, 5), (3, 1), (1, 9);
SELECT * FROM h2;
CREATE TABLE k1 (
id INT NOT NULL,
name VARCHAR(20),
UNIQUE KEY (id)
)
PARTITION BY KEY()
PARTITIONS 2;
Subpartitioning
Subpartitioning—also known as composite partitioning—is the further division of each
partition in a partitioned table. Consider the following CREATE TABLE statement: