Oracle Database Administration Lecture 2 SQL language Types of SQL statements • DDL (Data Definition Language) : create, drop, alter, for example: CREATE TABLE • DML (Data Modification Language): select, update, delete, insert • Transaction control statements: commit, rollback, savepoint • Session control statements: alter • System control statements: alter session system DML Statements: SELECT • SELECT – – – query data, does not modify tables does not lock (unless FOR UPDATE) SELECT * FROM users WHERE id = 1 FOR UPDATE – does not wait for any locks (unless FOR UPDATE) DML Statements: UPDATE • UPDATE – update data in one table (any number of rows) – locks updated data (until transaction end) – waits for locks if data is locked (can cause deadlock) – syntax: UPDATE table SET col1 = value1, col2 = value2 [ WHERE ...] DML Statements: DELETE • DELETE – deletes rows from one table (any number of rows) – locks deleted data (update will wait) – waits for locks if data is locked (can cause deadlock) – syntax: DELETE FROM table [ WHERE ... ] DML Statements: INSERT • INSERT – inserts one row or multiple rows – can sometimes wait for a lock Syntax: INSERT INTO table (col1, col2) VALUES (val1, val2) or INSERT INTO table VALUES (val1, val2) or INSERT INTO table (col1, col2) SELECT val1, val2 FROM ... (regular select statement) SELECT – basic syntax • Simple version: SELECT column_list FROM table [WHERE condition] • Example with table alias: SELECT u.last_name, u.first_name FROM users u – u is an alias for table users • Column alias: SELECT count(*) AS cnt FROM users cnt is column alias for function count(*) SELECT – all columns • Select all columns from a table using “*” • The following statements are identical: – – – SELECT * FROM users SELECT users.* FROM users SELECT u.* FROM users u To select all columns and more, use the following syntax: SELECT u.*, UPPER(last_name) FROM users SELECT – other user tables • To select data from some other user: SELECT users.first_name, users.last_name FROM user_name.users • Note: user_name cannot be used in column list, the following is illegal: SELECT user_name.table1.col1, user_name.table1.col2 FROM user_name.table1 • To select data from other user’s table current must have one of the following: • SELECT privilege on the table • SELECT ANY TABLE system privilige WHERE condition • WHERE clause specifies what records to include • There can be any number of conditions combined with AND, OR, NOT • There also can be conditions: – EXISTS (subquery), NOT EXISTS (subquery) – value IN (subquery), value NOT IN (subquery) • SQL functions can be used: SELECT * FROM users WHERE hire_date > SYSDATE – 10 SELECT * FROM users WHERE LENGTH(last_name) > 20 WHERE condition examples SELECT * FROM departments WHERE EXISTS(SELECT * FROM employees WHERE employees.dept_id = departments.id) SELECT * FROM departments WHERE id IN (SELECT dept_id FROM employees) SQL Joins • Joining tables – selecting data from two or more tables at the same time. • Types of joins: – Inner joins – typical – Outer joins – Cross joins – rarely used, sometimes used by accident by writing incorrect SELECT statement INNER JOIN • Explicit syntax: use INNER JOIN keywords • Implicit syntax: – provide more than one table in FROM clause – provide join condition (in WHERE clause) – Joins without join condition produce Cross join Joins • Simple explicit join: SELECT student.id, group.id, student.name, group.name FROM student INNER JOIN group ON student.group_id = group.id • Implicit join: SELECT student.id, group.id, student.name, group.name FROM student, group WHERE student.group_id = group.id Cross join • Explicit notation: SELECT student.id, group.id, student.name, group.name FROM student CROSS JOIN group • Implicit notation: SELECT student.id, group.id, student.name, group.name FROM student, group in both cases: number of rows returned = number of students * number of groups Complex join select • Any number of tables can appear in SELECT statement, example: SELECT student.id, group.id, course.id, grade.grade student.name, group.name FROM student, group, course, grade, student_courses courses WHERE student.group_id = group.id AND courses.student_id = student.id AND courses.course_id = course.id AND grade.course_id = course.id AND student.id = grade.student_id Inner Joins • Statement: SELECT student.id, group.id, student.name, group.name FROM student, group WHERE student.group_id = group.id does not return empty groups. Outer joins • To return records with no matching join condition use outer join statement: SELECT student.id, group.id, student.name, group.name FROM student LEFT OUTER JOIN group ON student.group_id = group.id Left outer join always returns results from the “left” table (student), even if there are no matching rows in the right table (group) If there is no matching group: group.id IS NULL and group.name IS NULL Outer joins • RIGHT OUTER JOIN always returns results from the right table even if there are no matching rows in the left table • FULL OUTER JOIN returns results from both tables Oracle syntax for outer joins • Statement: SELECT student.id, group.id, student.name, group.name FROM student, group WHERE student.group_id (+) = group.id returns one record for each student and one record for empty group (student.id and student.name are NULL) Outer join • (+) operator can be on either side of the = operator: SELECT student.id, group.id, student.name, group.name FROM student, group WHERE student.group_id = group.id (+) returns all students including ones with no group • (+) operator cannot be on both sides of the = operator: WHERE student.group_id (+) = group.id (+) is illegal Self join • Table can be joined to itself – self join. • One of the tables must be aliased in the FROM clause: SELECT dept.id, parent_dept.id, FROM dept, dept as parent_dept WHERE dept.parent_id = parent_dept.id Group functions • Select statement can include group function(s) in the column clause: SELECT max(salary), min(salary) FROM employers WHERE employers.dept = 2 • Select statement with no GROUP BY clause return one record • Group functions: • count, sum • avg, min, max • stddev, variance (Oracle specific) Group functions • Statement with group function and no GROUP BY clause cannot have “regular” columns in SELECT list. The following is illegal: SELECT max(salary), min(salary), name FROM employers WHERE employers.dept = 2 Group by clause • Records can be grouped using specified columns: SELECT max(salary), min(salary), dept FROM employers WHERE dept != 2 GROUP BY dept • Select clause can only include: • group functions • columns from the GROUP BY clause Having clause • HAVING clause is used with GROUP BY statement • HAVING clause filters records returned after grouping • WHERE clause filters records before grouping SELECT max(salary), min(salary), dept FROM employers WHERE dept != 2 GROUP BY dept HAVING min(salary) > 100 UNION • UNION, UNION ALL, MINUS, INTERSECT combine results of two independent SELECT statements • Both statements must return the same number of columns with the same data types • Column names are taken from the first SELECT statement • MINUS and INTERSECT statements can be resource consuming SELECT student.name FROM student UNION ALL SELECT teacher.name FROM teacher ORDER BY • ORDER BY specifies how records are sorted • ORDER BY clause can include: • column name or column index (1-based) • sort order (ASC or DESC) SELECT name, salary FROM employers ORDER BY salary DESC, 1 ASC SELECT name as personName, salary FROM employers ORDER BY salary DESC, personName ASC Sub-selects SELECT name, salary FROM employers WHERE salary = (SELECT MIN(salary) FROM employers) • In Oracle sub selects can be used in: • WHERE clause • FROM clause • SELECT clause • ORDER BY clause Sub-selects • FROM clause sub-select SELECT COUNT(*) FROM (SELECT MAX(salary) FROM employers) • SELECT clause SELECT ID, (SELECT MAX (salary) FROM employers WHERE employers.ID = dept.ID) FROM dept Sub-selects • ORDER BY clause sub-select SELECT ID FROM dept ORDER BY (SELECT MAX (salary) FROM employers WHERE employers.dept = dept.ID) WITH clause • WITH clause lets you assign a name to a subquery block. The query can be then referenced in many places by specifying query name WITH w AS ( SELECT id FROM emp WHERE emp.status = 'ACTIVE') SELECT * FROM w emp1 WHERE EXISTS (SELECT * FROM w emp2 WHERE emp1.id = emp2.boss_id) Oracle extensions • ROWID pseudo column – unique identifier of a row in entire database. Will not change when the row is updated SELECT ROWID, ID FROM student ....... DELETE FROM student WHERE ROWID = ‘....’ Oracle extensions • ROWNUM pseudo column – numbers rows (starting from 1) that are returned in a query. • Can be used to limit the number of rows returned: SELECT * FROM student WHERE ROWNUM <= 100 returns at most 100 rows DELETE FROM student WHERE ROWNUM <= 100 deletes at most 100 rows • ROWNUMs are assigned before the rows are ordered SELECT * FROM student WHERE ROWNUM <= 100 ORDER BY student.name DESC Oracle extensions • To get first 100 students in alphabetical order use the following statement: SELECT * FROM (SELECT FROM ORDER BY WHERE ROWNUM <= * students student NAME DESC) 100 Oracle extensions • Hierarchical queries: for table that references itself • Special CONNECT BY clause SELECT FROM CONNECT BY START WITH * employers boss_id = PRIOR id id = 1; • Selects all employers who’s boss (direct or not) is employer with ID = 1 Hierarchical queries • Special LEVEL pseudo-column is available in hierarchical queries: SELECT level, e.* FROM employers e CONNECT BY e.boss_id = PRIOR e.id START WITH e.id = 1; Practice SQL statements create table employees ( id number, name varchar2(100), boss_id number, dept_id number, salary number ); create table departments ( id number, name varchar2(100)); • Select total number of employees • Select total salary paid to all employees • Select department name, total salary, average salary, number of employees in each department (including departments with no employees) • Select employees with highest salary in each department • Select employees that earn more than their direct boss Practice SQL statements • Select employees that earn more than their direct or indirect boss • Select department where works the employee with the lowest salary • Select five employees with the highest salaries • Select employees from 6 - 10 on the salary list (from 6th to 10th person sorting by salary) (!) • Select employers that earn more than average in their department • Select departments with average salary higher than total average salary in the company • Select employees that have more than 5 subordinates (direct or indirect)