MySQL/Language

From testwiki
Revision as of 21:36, 1 March 2008 by imported>Eric Evers (Using NULL)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Browsing the databases

List databases

SHOW DATABASES;

List tables

USE `database`;
SHOW TABLES;
SHOW TABLES FROM `database`;

List fields

DESCRIBE `table`;
DESCRIBE `database`.`table`;
EXPLAIN `table`; --synonym
SHOW FIELDS FROM `table`; -- synonym
SHOW COLUMNS FROM `table`; --synonym

information_schema

information_schema is a virtual database provided by MySQL 5 and later, that contains metadata about the server and the databases.


Specifying table names

In this book, we will quote the MySQL identifiers (tables names, fields, etc.) using backquotes (`).

Most often, this is optional. However, this allows better error messages from MySQL. For example, this error is not very helpful:

mysql> SELECT user_id, group_id FROM user,group LIMIT 1;
ERROR 1064 (42000): You have an error in your SQL syntax;
 check the manual that corresponds to your MySQL server version
 for the right syntax to use near 'group LIMIT 1' at line 1

But this one is better:

mysql> SELECT user_id, group_id FROM `user`,`group` LIMIT 1;
ERROR 1146 (42S02): Table 'savannah.group' doesn't exist

Ok, it was just a missing s:

mysql>  SELECT user_id, group_id FROM `user`,`groups` LIMIT 1;
+---------+----------+
| user_id | group_id |
+---------+----------+
|     100 |        2 |
+---------+----------+
1 row in set (0.02 sec)

However, this is not a portable syntax. The SQL standard recommends the user of a double quote ("). If you want to write portable SQL quote, do not quote the identifiers. But is there something like portable SQL, even remotely? ;)


Template:Mergeto

Definitions: what are DDL, DML and DQL?

  • DDL (Data Definition Language) refers to the CREATE, ALTER and DROP TABLE statements
  • DML (Data Manipulation Language) refers to the INSERT, UPDATE and DELETE statements
  • DQL (Data Query Language) refers to the SELECT statements
  • DCL (Data Control Language) refers to the GRANT and REVOKE statements

User Variables

  • The ability to set variables in a statement with the := assignment operator:
  • For e.g. (@total) to calculate the total in an example, you have to have the total column first because it must be calculated before the individual percentage calculations
  • User variables are set for the duration of the thread.
  • In the vast majority of cases you'd use a programming language to do this sort of thing.
  • Mysql variables can be useful when working on the Mysql command line.
  • If no records are returned, the user variable will not be set for that statement.
  • A user variable set in the field list cannot be used as a condition.
select @test := 2;
select @test + 1
  • The value of a variable is set with the SET statement or in a SELECT statement with :=
set @startdate='some_start_date', @enddate='some_end_date'
SELECT @toremember:=count(*) FROM membros;
select @numzero := count(*) from table1 where field=0; 
select @numdistinct := count(distinct field) from table1 where field <> 0 ; 
select @numzero @numdistinct;

Alias

A select expression may be given an alias using AS. The alias is used as the expression's column name and can be used with order by or having clauses. For e.g.

SELECT 
    CONCAT(last_name,' ', first_name) AS full_name 
FROM
    mytable 
ORDER BY
    full_name

A table name can have a shorter name for reference using AS. You can omit the AS word and still use aliasing. For e.g.

SELECT
    COUNT(B.Booking_ID), U.User_Location 
FROM
    Users U
LEFT OUTER JOIN
    Bookings AS B
ON 
    U.User_ID    = B.Rep_ID AND
    B.Project_ID = '10'
GROUP BY
    (U.User_Location)

Aliasing plays a crucial role while you are using self joins. For e.g. people table has been referred to as p and c aliases!

SELECT
    p.name                                   AS parent,
    c.name                                   AS child,
    MIN((TO_DAYS(NOW())-TO_DAYS(c.dob))/365) AS minage
FROM
    people AS p 
LEFT JOIN
    people AS c 
ON
    p.name=c.parent WHERE c.name IS NOT NULL
GROUP BY
    parent HAVING minage > 50 ORDER BY p.dob;

Queries

SELECT

select syntax is as follows:

SELECT *
FROM table
WHERE condition

IN and NOT IN

SELECT id
FROM stats
WHERE position IN ('Manager', 'Staff')
SELECT ownerid, 'is in both orders & antiques'
FROM orders, antiques WHERE ownerid = buyerid
UNION
SELECT buyerid, 'is in antiques only'
FROM antiques WHERE buyerid NOT IN (SELECT ownerid FROM orders)

EXISTS and ALL

(Compatible: Mysql 4+)

SELECT ownerfirstname, ownerlastname
FROM owner 
WHERE EXISTS (SELECT * FROM antiques WHERE item = 'chair')
SELECT buyerid, item 
FROM antiques
WHERE price = ALL (SELECT price FROM antiques)

UNION and UNION All

(Compatible: Mysql 4+)

Following query will return all the records from both tables.

SELECT * FROM english 
UNION ALL
SELECT * FROM hindi

UNION is the same as UNION DISTINCT.
If you type only UNION, then it is considered that you are asking for distinct records. If you want all records, you have to use UNION ALL.

SELECT word FROM word_table WHERE id = 1
UNION
SELECT word FROM word_table WHERE id = 2
(SELECT magazine FROM pages)
UNION DISTINCT
(SELECT magazine FROM pdflog)
ORDER BY magazine
(SELECT ID_ENTRY FROM table WHERE ID_AGE = 1)
UNION DISTINCT 
(SELECT ID_ENTRY FROM table WHERE ID_AGE=2)

Joins

The Most important aspect of SQL is its relational features. You can query, compare and calculate two different tables having entirely different structure. Joins and subselects are the two methods to join tables. Both methods of joining tables should give the same results. The natural join is faster on most SQL platforms.

In the following example a student is trying to learn what the numbers are called in hindi.

CREATE TABLE english (Tag int, Inenglish varchar(255));
CREATE TABLE hindi (Tag int, Inhindi varchar(255));
INSERT INTO english (Tag, Inenglish) VALUES (1, 'One');
INSERT INTO english (Tag, Inenglish) VALUES (2, 'Two');
INSERT INTO english (Tag, Inenglish) VALUES (3, 'Three');
INSERT INTO hindi (Tag, Inhindi) VALUES (2, 'Do');
INSERT INTO hindi (Tag, Inhindi) VALUES (3, 'Teen');
INSERT INTO hindi (Tag, Inhindi) VALUES (4, 'Char');
 select * from english select * from hindi
TagInenglish Tag Inhindi
1 One 2 Do
2 Two 3 Teen
3 Three 4 Char

Cartesian join

A Cartesian join is when you join every row of one table to every row of another table.

SELECT * FROM english, hindi
TagInenglishTag Inhindi
1 One 2 Do
2 Two 2 Do
3 Three 2 Do
1 One 3 Teen
2 Two 3 Teen
3 Three 3 Teen
1 One 4 Char
2 Two 4 Char
3 Three 4 Char

Inner Join

SELECT hindi.Tag, english.Inenglish, hindi.Inhindi
FROM english, hindi
WHERE english.Tag = hindi.Tag
Tag Inenglish Inhindi
2 Two Do
3 Three Teen

You can also write the same query as

SELECT hindi.Tag, english.Inenglish, hindi.Inhindi
FROM english INNER JOIN hindi
ON english.Tag = hindi.Tag

Natural Joins using "using" (Compatible: MySQL 4+; but changed in MySQL 5) The following statement using "USING" method will display the same results.

SELECT hindi.tag, hindi.Inhindi, english.Inenglish
FROM hindi NATURAL JOIN english
USING (Tag)

Outer Joins

Tag Inenglish Tag Inhindi
1 One  
2 Two 2 Do
3 Three 3 Teen
    4 Char

LEFT JOIN / LEFT OUTER JOIN

The syntax is as follows:

SELECT field1, field2 FROM table1 LEFT JOIN table2 ON field1=field2
SELECT e.Inenglish as English, e.Tag, '--no row--' as Hindi
FROM english AS e LEFT JOIN hindi AS h
ON e.Tag=h.Tag 
WHERE h.Inhindi IS NULL
English  tag   Hindi
One      1     --no row-

Right Outer Join

SELECT '--no row--' AS English, h.tag, h.Inhindi AS Hindi
FROM english AS e RIGHT JOIN hindi AS h
ON e.Tag=h.Tag
WHERE e.Inenglish IS NULL

English tag Hindi --no row-- 4 Char

  • Make sure that you have the same name and same data type in both tables.
  • The keywords LEFT and RIGHT are not absolute, they only operate within the context of the given statement: we can reverse the order of the tables and reverse the keywords, and the result would be the same.
  • If the type of join is not specified as inner or outer then it will be executed as an INNER JOIN.

Full Outer Join

As for v5.1, MySQL does not provide FULL OUTER JOIN. You may emulate this using a series of UNIONed SELECT statements.

Multiple joins

It is possible to join more than just two tables:

SELECT ... FROM a JOIN (b JOIN c on b.id=c.id) ON a.id=b.id

Here is an example from Savane:

mysql> SELECT group_type.type_id, group_type.name, COUNT(people_job.job_id) AS count 
       FROM group_type
        JOIN (groups JOIN people_job ON groups.group_id = people_job.group_id) 
        ON group_type.type_id = groups.type
       GROUP BY type_id ORDER BY type_id
+---------+--------------------------------------+-------+
| type_id | name                                 | count |
+---------+--------------------------------------+-------+
|       1 | Official GNU software                |   148 |
|       2 | non-GNU software and documentation   |   268 |
|       3 | www.gnu.org portion                  |     4 |
|       6 | www.gnu.org translation team         |     5 |
+---------+--------------------------------------+-------+
4 rows in set (0.02 sec)

Subqueries

(Compatible: Mysql 4.1 and later...Bold text)

  • SQL subqueries let you use the results of one query as part of another query.
  • Subqueries are often natural ways of writing a statement.
  • Let you break a query into pieces and assemble it.
  • Allow some queries that otherwise can't be constructed. Without using a subquery, you have to do it in two steps.
  • Subqueries always appear as part of the WHERE (or HAVING) clause.
  • Only one field can be in the subquery SELECT. It means Subquery can only produce a single column of data as its result.
  • ORDER BY is not allowed; it would not make sense.
  • Usually refer to name of a main table column in the subquery.
  • This defines the current row of the main table for which the subquery is being run. This is called an outer reference.

For e.g. If RepOffice= OfficeNbr from Offices table, list the offices where the sales quota for the office exceeds the sum of individual salespersons' quotas

SELECT City FROM Offices WHERE Target > ???

??? is the sum of the quotas of the salespeople, i.e.

SELECT SUM(Quota)
FROM SalesReps 
WHERE RepOffice = OfficeNbr

We combine these to get

SELECT City FROM Offices 
WHERE Target > (SELECT SUM(Quota) FROM SalesReps 
WHERE RepOffice = OfficeNbr)

Display all customers with orders or credit limits > $50,000. Use the DISTINCT word to list the customer just once.

SELECT DISTINCT CustNbr 
FROM Customers, Orders 
WHERE CustNbr = Cust AND (CreditLimit>50000 OR Amt>50000);

Data manipulation

INSERT

The syntax is as follows:

Insert value1 into Column1, value2 into Column2, and value3 into Column3:

INSERT INTO TableName (Column1, Column2, Column3)
VALUES (value1, value2, value3)

Insert one record (values are inserted in the order that the columns appear in the database):

INSERT INTO TableName
VALUES (value1, value2, value3)

Insert two records:

INSERT INTO TableName
VALUES (value1, value2, value3), (value4, value5, value6)
INSERT INTO antiques VALUES (21, 01, 'Ottoman', 200.00);
INSERT INTO antiques (buyerid, sellerid, item) VALUES (01, 21, 'Ottoman');

You can also insert records 'selected' from other table.

INSERT INTO table1(field1, field2)
SELECT field1, field2
FROM table2
INSERT INTO World_Events SELECT * FROM National_Events

UPDATE

The syntax is:

UPDATE table SET field = newvalue WHERE criteria

Examples are:

UPDATE owner SET ownerfirstname = 'John'
  WHERE ownerid = (SELECT buyerid FROM antiques WHERE item = 'Bookcase');

UPDATE antiques SET price = 500.00 WHERE item = 'Chair';

UPDATE order SET discount=discount * 1.05

UPDATE tbl1 JOIN tbl2 ON tbl1.ID = tbl2.ID
  SET tbl1.col1 = tbl1.col1 + 1
  WHERE tbl2.status='Active'

UPDATE tbl SET names = REPLACE(names, 'aaa', 'zzz')

UPDATE products_categories AS pc
  INNER JOIN products AS p ON pc.prod_id = p.id
  SET pc.prod_sequential_id = p.sequential_id

UPDATE table_name SET col_name =
  REPLACE(col_name, 'host.domain.com', 'host2.domain.com')


It is currently not possible to update a table while performing a subquery on the same table. For example, if I want to reset a password I forgot in SPIP:

mysql> UPDATE spip_auteurs SET pass =
 (SELECT pass FROM spip_auteurs WHERE login='paul') where login='admin';
ERROR 1093 (HY000): You can't specify target table 'spip_auteurs' for update in FROM clause

TODO: [1] describes a work-around that I couldn't make to work with MySQL 4.1. Currently the work-around is not use 2 subqueries, possibly with transactions.

REPLACE

REPLACE works exactly like INSERT, except that if an old record in the table has the same value as a new record for a PRIMARY KEY or a UNIQUE index, the old record is deleted before the new record is inserted.

With IGNORE, invalid values are adjusted to the closest values and inserted; warnings are produced but the statement does not abort.

Prior to MySQL 4.0.1, INSERT ... SELECT implicitly operates in IGNORE mode. As of MySQL 4.0.1, specify IGNORE explicitly to ignore records that would cause duplicate-key violations.


DELETE

DELETE FROM table1
TRUNCATE table1
  • If you don't use a WHERE clause with DELETE, all records will be deleted.
  • It can be very slow in a large table.
  • TRUNCATE will do it quickly by DROPping and reCREATE-ing the table.
  • DELETE informs you how many rows have been removed, but TRUNCATE doesn't.
DELETE FROM antiques
  WHERE item = 'Ottoman'

DROP

DROP TABLE products

will completely delete the records as well as the columns.

Table manipulation

CREATE TABLE

Create table syntax is: Create table tablename (FieldName1 DataType,
FieldName2 DataType)

The rows returned by the "select" query can be saved as a new table. The datatype will be the same as the old table. For e.g. CREATE TABLE LearnHindi
select english.tag, english.Inenglish as english, hindi.Inhindi as hindi
FROM english, hindi
WHERE english.tag = hindi.tag

ALTER TABLE

alter table command can be used when you want to add / delete the columns or change the data type.

ALTER TABLE awards
ADD COLUMN AwardCode int(2)

ALTER TABLE awards
ALTER COLUMN AwardCode VARCHAR(2) NOT NULL

ALTER TABLE awards
DROP COLUMN AwardCode


Using NULL

Null is a special logical value in SQL. Most programming languages have 2 values of logic: True and False. SQL also has NULL which means Unknown. A NULL value can be set.

INSERT into Singer
       (F_Name, L_Name, Birth_place, Language) 
       values 
       ("", "Homer", NULL, "Greek"),
       ("", "Sting", NULL, "English"),
       ("Jonny", "Five", NULL, "Binary");

Do not quote the NULL. If you quote a Null then you name the person NULL. For some strange reason, NULLs do not show visually on windows XP in Varchar fields but they do in Fedora's version, so versions of mysql can give different outputs. Here we set the value of Sting and Homer's first name to a zero length string "", because we KNOW they have NO first name, but we KNOW we do not know the place they were born. To check for a NULLs use

SELECT * from Singer WHERE Birth_place IS NULL;
or
SELECT * from Singer WHERE Birth_place IS NOT NULL;

Remember, COUNT never counts NULLS.

select count(Birth_place) from Singer;
0
and sum(NULL) gives a NULL answer.

Dealing with NULL

The function 'COALESCE' can simplify working with null values. for example, to avoid showing null values by treating null as zero, you can type:

SELECT COALESCE(colname,0) from table where COALESCE(colname,0) > 1;

In a date field, to treat NULL as the current date:

ORDER BY (COALESCE(TO_DAYS(date),TO_DAYS(CURDATE()))-TO_DAYS(CURDATE()))


EXP(SUM(LOG(COALESCE(*the field you want to multiply*,1))) 

The coalesce() function is there to guard against trying to calculate the logarithm of a null value and may be optional depending on your circumstances.

SELECT t4.gene_name, COALESCE(g2d.score,0), 
COALESCE(dgp.score,0), COALESCE(pocus.score,0) 
FROM t4 
LEFT JOIN g2d ON t4.gene_name=g2d.gene_name 
LEFT JOIN dgp ON t4.gene_name=dgp.gene_name 
LEFT JOIN pocus ON t4.gene_name=pocus.gene_name;

Use of IFNULL() in your SELECT statement is to make the NULL any value you wish.

IFNULL(expr1,expr2)

If expr1 is not NULL, IFNULL() returns expr1, else it returns expr2.

IFNULL() returns a numeric or string value, depending on the context in which it is used:

mysql> SELECT IFNULL(1,0);
-> 1
mysql> SELECT IFNULL(NULL,10);
-> 10
mysql> SELECT IFNULL(1/0,10);
-> 10
mysql> SELECT IFNULL(1/0,'yes');
-> 'yes'

Null handling can be very counter intuitive and could cause problems if you have an incorrect function in a delete statement that returns null. For example the following query will delete all entries.

DELETE FROM my_table WHERE field > NULL (or function returning NULL)

If you want to have NULL values presented last when doing an ORDER BY, try this:

SELECT * FROM my_table ORDER BY ISNULL(field), field [ ASC | DESC ]

Reserved Words

Difficult Column Names, Like `DATE` -- use backtick. If using "date" as a column name, enclose it in backticks ` as follows:

CREATE TABLE IF NOT EXISTS stocks (
  pkey int NOT NULL auto_increment,
  `date` date,
  ticker varchar(5),
  open decimal (9,2),
  high decimal (9,2),
  low decimal (9,2),
  close decimal (9,2),
  volume int,
  timeEnter timestamp(14),
  PRIMARY KEY (pkey)
);

Data Types

varchar

VARCHAR is shorthand for CHARACTER VARYING. 'n' represents the maximum column length (upto 255 characters) char(n) is similar to varchar(n) with the only difference that char will occupy fixed length of space in the database whereas varchar will need the space to store the actual text. For example, a VARCHAR(10) column can hold a string with a maximum length of 10 characters. The actual storage required is the length of the string (L), plus 1 byte to record the length of the string. For the string 'abcd', L is 4 and the storage requirement is 5 bytes.

text

A BLOB or TEXT column with a maximum length of 65,535 characters.

integer

Specifying an n value has no effect whatsoever. Regardless of a supplied value for n, maximum (unsigned) value stored is 429 crores. If you want to add negative numbers, add the "signed" keyword next to it.

decimal

decimal(n,m) decimal(4,2) means numbers upto 99.99 (and NOT 9999.99 as you may expect) can be saved. Four digits with the last 2 reserved for decimal.

Dates

Out of the three types DATETIME, DATE, and TIMESTAMP, the DATE type is used when you need only a date value, without a time part. MySQL retrieves and displays DATE values in 'YYYY-MM-DD' format. The DATETIME type is used when you need values that contain both date and time information. The difference between DATETIME and TIMESTAMP is that the TIMESTAMP range is limited to 1970-2037 (see below).

TIME can be used to only store the time of day (HH:MM:SS), without the date. It can also be used to represent a time interval (for example: -02:00:00 for "two hours in the past"). Range: '-838:59:59' => '838:59:59'.

YEAR can be used to store the year number only.


If you manipulate dates, you have to specify the actual date, not only the time - that is, MySQL will not automagically use today as the current date. On the contrary, MySQL will even interpret the HH:MM:SS time as a YY:MM:DD value, which will probably be invalid.


The following examples show the precise date range for Unix-based timestamps, which starts at the Unix Epoch and stops just before the first new year before the 2311 usual limit (2038).

mysql> SET time_zone = '+00:00'; -- GMT
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT FROM_UNIXTIME(-1);
+-------------------+
| FROM_UNIXTIME(-1) |
+-------------------+
| NULL              |
+-------------------+
1 row in set (0.00 sec)

mysql> SELECT FROM_UNIXTIME(0); -- "Epoch"
+---------------------+
| FROM_UNIXTIME(0)    |
+---------------------+
| 1970-01-01 00:00:00 |
+---------------------+
1 row in set (0.00 sec)

mysql> SELECT FROM_UNIXTIME(2145916799);
+---------------------------+
| FROM_UNIXTIME(2145916799) |
+---------------------------+
| 2037-12-31 23:59:59       |
+---------------------------+
1 row in set (0.00 sec)

mysql> SELECT FROM_UNIXTIME(2145916800);
+---------------------------+
| FROM_UNIXTIME(2145916800) |
+---------------------------+
| NULL                      |
+---------------------------+
1 row in set (0.00 sec)

set and enum

A SET datatype can hold any number of strings from a predefined list of strings specified during table creation. The SET datatype is similar to the ENUM datatype in that they both work with predefined sets of strings, but where the ENUM datatype restricts you to a single member of the set of predefined strings, the SET datatype allows you to store any of the values together, from none to all of them.


Import / export

Aside from mysqldump (cf. MySQL/Administration), you can also export raw data using:

SELECT ... FROM table INTO OUTFILE 'path'
LOAD DATA INFILE 'path' INTO TABLE table

Examples:

SELECT * FROM destinataire INTO OUTFILE '/tmp/test' WHERE id IN (41, 141, 260, 317, 735, 888, 1207, 2211);
# in another database/computer/etc.:
LOAD DATA INFILE '/tmp/test' INTO TABLE destinataire;

Beware that the MySQL daemon itself will write the file, not the user you run the MySQL client with. The file will be stored on the server, not on your host. Moreover, the server will need write access to the path you specify (usually, the server can _not_ write in your home directory, e.g.). Hence why we (unsecurely) used /tmp in the examples.

Functions

Date and time

SELECT * FROM mytable
 WHERE datetimecol >= (CURDATE() - INTERVAL 1 YEAR)  AND
 datetimecol < (CURDATE() - INTERVAL 1 YEAR) INTERVAL 1 DAY;
SELECT IF(DAYOFMONTH(CURDATE()) <= 15,
 DATE_FORMAT(CURDATE(), '%Y-%m-15'),
 DATE_FORMAT(CURDATE() + INTERVAL 1 MONTH, '%Y-%m-15')) AS next15
FROM table;
SELECT YEAR('2002-05-10'), MONTH('2002-05-10'), DAYOFMONTH('2002-05-10')
SELECT PurchaseDate FROM table WHERE YEAR(PurchaseDate) <= YEAR(CURDATE())
SELECT columns FROM table
WHERE start_time >= '2004-06-01 10:00:00' AND end_time <= '2004-06-03 18:00:00'
SELECT * FROM t1
WHERE DATE_FORMAT(datetime_column, '%T') BETWEEN 'HH:MM:SS' AND 'HH:MM:SS'
SELECT Start_time, End_time FROM Table
WHERE Start_time >= NOW() - INTERVAL 4 HOUR

SELECT NOW() + INTERVAL 60 SECOND
SELECT UNIX_TIMESTAMP('2007-05-01'); -- 1177970400
SELECT FROM_UNIXTIME(1177970400); -- 2007-05-01 00:00:00

Syntax

When you use DATE_FORMAT(), if I have a space character between DATE_FORMAT and the ( I get an error. Try writing it like: SELECT DATE_FORMAT( "20040601123456", '%Y-%m-%d' );

You can't use a value calculated in the SELECT clause as a constraint in the WHERE clause (its a chicken & egg problem); the WHERE clause is what determines the values in the SELECT clause. What you want is the HAVING clause which is applied *after* all matching rows have been found.

Exercises

Practicing SELECT

Table `list`

ID Name Surname FlatHave FlatWant
1 Shantanu Oak Goregaon  
2 Shantanu Oak Andheri  
3 Shantanu Oak   Dadar
4 Ram Joshi   Goregaon
5 Shyam Sharma   Andheri
6 Ram Naik Sion  
7 Samir Shah Parle  
8 Ram Joshi Dadar  
9 Shyam Sharma Dadar  

Exercise I - Questions

  • Who has a flat in "Goreagon" and who wants to buy one?
  • Who has a flat in "Parle" and who wants to buy one?
  • Where does "Shantanu Oak" own the flats and where does he want to buy one?
  • How many entries have been recorded so far?
  • How many flats are there for sale?
  • What are the names of our clients?
  • How many clients do we have?
  • List the customers whose name start with "S"?
  • Rearrange the list Alphabetically sorted.

Exercise I - Answers

  • select * from list where FlatHave = "Goregaon" or FlatWant = "Goregaon"
  • select * from list where FlatHave = "Parle" or FlatWant = "Parle"
  • select * from list where Name = "Shantanu" and Surname = "Oak"
  • select count(*) from list
  • select count(FlatHave) from list where FlatHave is not null
  • select distinct Name, Surname from list
  • select count(distinct Name, surname) from list
  • select * from list where Name like "S%"
  • select Surname, Name, FlatHave, FlatWant from list order by Name

Table `grades`

ID Name Math Physics Literature
1 John 68 37 54
2 Jim 96 89 92
3 Bill 65 12 57
4 Jeri 69 25 82


Exercise II - Questions

  • A list of all students who scored over 90 on his or her math paper?
  • A list of all students who scored more than 85 in all subjects?
  • Declare Results: Print the results of all students with result column.
  • Find out total marks of all the students.
  • What are the average marks of the class for each subject?
  • What are the minimum marks in Math?
  • What are the maximum marks in Math?
  • Who got the highest marks in Math?

Exercise II - Answers

Note: many problems have more than one correct solution.

  • SELECT * FROM grades WHERE math > 90
  • SELECT name FROM grades WHERE math > 85 AND physics > 85 AND literature > 85
  • SELECT *, IF( (math <= 35 OR physics <= 35 OR literature <= 35), 'fail', 'pass') AS result FROM grades ORDER BY result DESC
  • SELECT name, math+physics+literature FROM grades
  • SELECT AVG(math), AVG(physics), AVG(literature) FROM grades
  • SELECT MIN(math) FROM grades
  • SELECT MAX(math) FROM grades
  • SELECT * FROM students ORDER BY math DESC LIMIT 1

Examples

Finding Duplicates

SELECT Vendor, ID, Count(1) as dupes
FROM table_name
GROUP BY Vendor, ID HAVING Count(1) >1
SELECT txt, COUNT(*)
FROM dupes
GROUP BY txt HAVING COUNT(*) > 1;
SELECT id, COUNT( id ) AS cnt, 
FROM myTable
GROUP BY id HAVING cnt > 1

Remove duplicate entries.

Assume the following table and data.

CREATE TABLE IF NOT EXISTS dupTest
(pkey int(11) NOT NULL auto_increment,
a int, b int, c int, timeEnter timestamp(14),
PRIMARY KEY (pkey));

insert into dupTest (a,b,c) values (1,2,3),(1,2,3),
(1,5,4),(1,6,4);

Note, the first two rows contains duplicates in columns a and b. It contains other duplicates; but, leaves the other duplicates alone.

ALTER IGNORE TABLE dupTest ADD UNIQUE INDEX(a,b);