0% found this document useful (0 votes)
7 views

IT (802) Practical

Information technology practical class 12

Uploaded by

luffyko457
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views

IT (802) Practical

Information technology practical class 12

Uploaded by

luffyko457
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 12

MySQL Practical

Common Queries

Table of Contents
1. The Maximum Value for a Column .........................................................................................................
2. The Row Holding the Maximum of a Certain Column .............................................................................
3. Maximum of Column per Group..............................................................................................................
4. The Rows Holding the Group-wise Maximum of a Certain Column .........................................................
5. Using User-Defined Variables .................................................................................................................
6. Using Foreign Keys ................................................................................................................................
7. Searching on Two Keys..........................................................................................................................
8. Calculating Visits Per Day ......................................................................................................................
9. Using AUTO_INCREMENT .....................................................................................................................

The Maximum Value for a Column


“What is the highest item number?”

SELECT MAX(article) AS article FROM shop;

+---------+
| article |
+---------+
| 4 |
+---------+

The Row Holding the Maximum of a Certain Column


Task: Find the number, dealer, and price of the most expensive article.

This is easily done with a subquery:


SELECT article, dealer, price
FROM shop
WHERE price=(SELECT MAX(price) FROM shop);
+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
| 0004 | D | 19.95 |
+---------+--------+-------+

Another solution is to use a LEFT JOIN, as shown here:


SELECT s1.article, s1.dealer, s1.price
FROM shop s1
LEFT JOIN shop s2 ON s1.price < s2.price
WHERE s2.article IS NULL;

You can also do this by sorting all rows descending by price and get only the first row using the MySQL-
specific LIMIT clause, like this:
SELECT article, dealer, price
FROM shop
ORDER BY price DESC
LIMIT 1;

Note

If there were several most expensive articles, each with a price of 19.95, the LIMIT
solution would show only one of them.

Maximum of Column per Group


Task: Find the highest price per article.
SELECT article, MAX(price) AS price
FROM shop
GROUP BY article
ORDER BY article;
+---------+-------+
| article | price |
+---------+-------+
| 0001 | 3.99 |
| 0002 | 10.99 |
| 0003 | 1.69 |
| 0004 | 19.95 |
+---------+-------+

The Rows Holding the Group-wise Maximum of a Certain Column


Task: For each article, find the dealer or dealers with the most expensive price.

This problem can be solved with a subquery like this one:


SELECT article, dealer, price
FROM shop s1
WHERE price=(SELECT MAX(s2.price)
FROM shop s2
WHERE s1.article = s2.article)
ORDER BY article;
+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
| 0001 | B | 3.99 |
| 0002 | A | 10.99 |
| 0003 | C | 1.69 |
| 0004 | D | 19.95 |
+---------+--------+-------+

The preceding example uses a correlated subquery, which can be inefficient (see Correlated Subqueries).
Other possibilities for solving the problem are to use an uncorrelated subquery in the FROM clause or a
LEFT JOIN.

Uncorrelated subquery:
SELECT s1.article, dealer, s1.price
FROM shop s1
JOIN (
SELECT article, MAX(price) AS price
FROM shop
GROUP BY article) AS s2
ON s1.article = s2.article AND s1.price = s2.price
ORDER BY article;

LEFT JOIN:
SELECT s1.article, s1.dealer, s1.price
FROM shop s1
LEFT JOIN shop s2 ON s1.article = s2.article AND s1.price < s2.price
WHERE s2.article IS NULL
ORDER BY s1.article;

The LEFT JOIN works on the basis that when s1.price is at its maximum value, there is no s2.price
with a greater value and thus the corresponding s2.article value is NULL. See JOIN Clause.

Using User-Defined Variables


You can employ MySQL user variables to remember results without having to store them in temporary
variables in the client. (See User-Defined Variables.)

For example, to find the articles with the highest and lowest price you can do this:
mysql> SELECT @min_price:=MIN(price),@max_price:=MAX(price) FROM shop;
mysql> SELECT * FROM shop WHERE price=@min_price OR price=@max_price;
+---------+--------+-------+
| article | dealer | price |
+---------+--------+-------+
| 0003 | D | 1.25 |
| 0004 | D | 19.95 |
+---------+--------+-------+

Note

It is also possible to store the name of a database object such as a table or a


column in a user variable and then to use this variable in an SQL statement;

however, this requires the use of a prepared statement. See Prepared Statements,
for more information.

Using Foreign Keys


MySQL supports foreign keys, which permit cross-referencing related data across tables, and foreign key
constraints, which help keep the related data consistent.

A foreign key relationship involves a parent table that holds the initial column values, and a child table with
column values that reference the parent column values. A foreign key constraint is defined on the child
table.

This following example relates parent and child tables through a single-column foreign key and shows
how a foreign key constraint enforces referential integrity.

Create the parent and child tables:


CREATE TABLE parent (
id INT NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE child (
id INT,
parent_id INT,
INDEX par_ind (parent_id),
FOREIGN KEY (parent_id)
REFERENCES parent(id)
) ENGINE=INNODB;

Insert a row into the parent table:


mysql> INSERT INTO parent (id) VALUES (1);
Verify that the data was inserted:
mysql> SELECT * FROM parent;
+----+
| id |
+----+
| 1 |
+----+

Insert a row into the child table:


mysql> INSERT INTO child (id,parent_id) VALUES (1,1);

The insert operation is successful because parent_id 1 is present in the parent table.

Insert a row into the child table with a parent_id value that is not present in the parent table:
mysql> INSERT INTO child (id,parent_id) VALUES(2,2);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails
(`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`)
REFERENCES `parent` (`id`))

The operation fails because the specified parent_id value does not exist in the parent table.

Try to delete the previously inserted row from the parent table:
mysql> DELETE FROM parent WHERE id VALUES = 1;
ERROR 1451 (23000): Cannot delete or update a parent row: a foreign key constraint fails

(`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`)


REFERENCES `parent` (`id`))

This operation fails because the record in the child table contains the referenced id (parent_id) value.

When an operation affects a key value in the parent table that has matching rows in the child table,
the result depends on the referential action specified by ON UPDATE and ON DELETE subclauses of
the FOREIGN KEY clause. Omitting ON DELETE and ON UPDATE clauses (as in the current child table
definition) is the same as specifying the RESTRICT option, which rejects operations that affect a key value
in the parent table that has matching rows in the parent table.

To demonstrate ON DELETE and ON UPDATE referential actions, drop the child table and recreate it
to include ON UPDATE and ON DELETE subclauses with the CASCADE option. The CASCADE option
automatically deletes or updates matching rows in the child table when deleting or updating rows in the
parent table.
DROP TABLE child;
CREATE TABLE child (
id INT,
parent_id INT,
INDEX par_ind (parent_id),
FOREIGN KEY (parent_id)
REFERENCES parent(id)
ON UPDATE CASCADE
ON DELETE CASCADE
) ENGINE=INNODB;

Insert the following rows into the child table:


mysql> INSERT INTO child (id,parent_id) VALUES(1,1),(2,1),(3,1);

Verify that the data was inserted:


child;
mysql> SELECT * FROM
+------+-----------+
| id | parent_id |
+------+-----------+
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
+------+-----------+

Update the id in the parent table, changing it from 1 to 2.


mysql> UPDATE parent SET id = 2 WHERE id = 1;

Verify that the update was successful:


mysql> SELECT * FROM parent;
+----+
| id |
+----+
| 2 |
+----+

Verify that the ON UPDATE CASCADE referential action updated the child table:
mysql> SELECT * FROM child;
+------+-----------+
| id | parent_id |
+------+-----------+
| 1 | 2 |
| 2 | 2 |

| 3 | 2 |
+------+-----------+

To demonstrate the ON DELTE CASCADE referential action, delete records from the parent table where the
parent_id = 2, which deletes all records in the parent table.
mysql> DELETE FROM parent WHERE id = 2;

Because all records in the child table are associated with parent_id = 2, the ON DELETE CASCADE
referential action removes all records from the child table:
mysql> SELECT * FROM child;
Empty set (0.00 sec)

For more information about foreign key constraints, see FOREIGN KEY Constraints.

Searching on Two Keys


An OR using a single key is well optimized, as is the handling of AND.

The one tricky case is that of searching on two different keys combined with OR:
SELECT field1_index, field2_index FROM test_table
WHERE field1_index = '1' OR field2_index = '1'

This case is optimized. See Index Merge Optimization.

You can also solve the problem efficiently by using a UNION that combines the output of two separate
SELECT statements. See UNION Clause.

Each SELECT searches only one key and can be optimized:


SELECT field1_index, field2_index
FROM test_table WHERE field1_index = '1'
UNION
SELECT field1_index, field2_index
FROM test_table WHERE field2_index = '1';
Calculating Visits Per Day
The following example shows how you can use the bit group functions to calculate the number of days per
month a user has visited a Web page.
CREATE TABLE t1 (year YEAR, month INT UNSIGNED,
day INT UNSIGNED);
INSERT INTO t1 VALUES(2000,1,1),(2000,1,20),(2000,1,30),(2000,2,2),
(2000,2,23),(2000,2,23);

The example table contains year-month-day values representing visits by users to the page. To determine
how many different days in each month these visits occur, use this query:
SELECT year,month,BIT_COUNT(BIT_OR(1<<day)) AS days FROM t1
GROUP BY year,month;

Which returns:
+------+-------+------+
| year | month | days |
+------+-------+------+
| 2000 | 1 | 3 |
| 2000 | 2 | 2 |
+------+-------+------+

The query calculates how many different days appear in the table for each year/month combination, with
automatic removal of duplicate entries.

Using AUTO_INCREMENT
The AUTO_INCREMENT attribute can be used to generate a unique identity for new rows:
CREATE TABLE animals (
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (id)
);
INSERT INTO animals (name) VALUES
('dog'),('cat'),('penguin'),
('lax'),('whale'),('ostrich');
SELECT * FROM animals;

Which returns:
+----+---------+
| id | name |
+----+---------+
| 1 | dog |
| 2 | cat |
| 3 | penguin |
| 4 | lax |
| 5 | whale |
| 6 | ostrich |
+----+---------+

No value was specified for the AUTO_INCREMENT column, so MySQL assigned sequence numbers
automatically. You can also explicitly assign 0 to the column to generate sequence numbers, unless the
NO_AUTO_VALUE_ON_ZERO SQL mode is enabled. For example:
INSERT INTO animals (id,name) VALUES(0,'groundhog');

If the column is declared NOT NULL, it is also possible to assign NULL to the column to generate sequence
numbers. For example:
INSERT INTO animals (id,name) VALUES(NULL,'squirrel');
When you insert any other value into an AUTO_INCREMENT column, the column is set to that value and
the sequence is reset so that the next automatically generated value follows sequentially from the largest
column value. For example:
INSERT INTO animals (id,name) VALUES(100,'rabbit');
INSERT INTO animals (id,name) VALUES(NULL,'mouse');
SELECT * FROM animals;
+-----+-----------+
| id | name |
+-----+-----------+
| 1 | dog |
| 2 | cat |
| 3 | penguin |
| 4 | lax |
| 5 | whale |
| 6 | ostrich |
| 7 | groundhog |
| 8 | squirrel |
| 100 | rabbit |
| 101 | mouse |
+-----+-----------+

Updating an existing AUTO_INCREMENT column value in an InnoDB table does not reset the
AUTO_INCREMENT sequence as it does for MyISAM and NDB tables.

You can retrieve the most recent automatically generated AUTO_INCREMENT value with the
LAST_INSERT_ID() SQL function or the mysql_insert_id() C API function. These functions are
connection-specific, so their return values are not affected by another connection which is also performing
inserts.

Use the smallest integer data type for the AUTO_INCREMENT column that is large enough to hold the
maximum sequence value you need. When the column reaches the upper limit of the data type, the
next attempt to generate a sequence number fails. Use the UNSIGNED attribute if possible to allow a
greater range. For example, if you use TINYINT, the maximum permissible sequence number is 127. For
TINYINT UNSIGNED, the maximum is 255. See Integer Types (Exact Value) - INTEGER, INT, SMALLINT,
TINYINT, MEDIUMINT, BIGINT for the ranges of all the integer types.

Note

For a multiple-row insert, LAST_INSERT_ID() and mysql_insert_id() actually


return the AUTO_INCREMENT key from the first of the inserted rows. This enables
multiple-row inserts to be reproduced correctly on other servers in a replication
setup.

To start with an AUTO_INCREMENT value other than 1, set that value with CREATE TABLE or ALTER
TABLE, like this:
mysql> ALTER TABLE tbl AUTO_INCREMENT = 100;

You might also like