SQL (4): Subqueries

22
SQL (4): Subqueries CS 4750 – Database Systems SUBQUERIES IN “WHERE”, SUBQUERIES IN “WITH”, SUBQUERIES IN SET OPERATIONS 1 [A. Silberschatz, H. F. Korth, S. Sudarshan, Database System Concepts, Ch.5.3]

Transcript of SQL (4): Subqueries

Page 1: SQL (4): Subqueries

SQL (4): SubqueriesCS 4750 – Database Systems

SUBQUERIES IN “WHERE”, SUBQUERIES IN “WITH”, SUBQUERIES IN SET OPERATIONS

1

[A. Silberschatz, H. F. Korth, S. Sudarshan, Database System Concepts, Ch.5.3]

Page 2: SQL (4): Subqueries

Subqueries: The Core Idea

The smaller the problem, the simpler to solve, the easier to debug

Page 3: SQL (4): Subqueries

SubqueriesSubquery = a query that is part of another query

A subquery can have subqueries

Usage:

Return a single constant that can be used to compute an associated value in a SELECTclause

Return a single constant that can be compared to another value in a WHERE clause

Return a relation that can be compared or evaluated in a WHERE clause

Return a relation that can be used as input for another query, in a FORM clause

3

Page 4: SQL (4): Subqueries

Subqueries in WHEREWHERE

HW_empempno ename job sal

7369 Smith Clerk 1200

7499 Allen Salesman 2000

7521 Ward Salesman 1650

7566 Jones Manager 3375

7654 Martin Salesman 1650

7698 Blake Manager 3250

7782 Clark Manager 2850

7788 Scott Analyst 3500

7839 King President 6500

7844 Turner Salesman 1900

7876 Adams Clerk 1500

7900 James Clerk 1350

7902 Ford Analyst 3500

7934 Miller Clerk 1700

SELECT E1.ename

FROM HW_emp E1

WHERE E1.sal =

(SELECT MAX(E2.sal)

FROM HW_emp AS E2

WHERE E1.job = E2.job)

[ WHERE ]

“Correlated”

ename

Allen

Jones

Scott

King

Ford

Miller

Page 5: SQL (4): Subqueries

Subqueries in WITH

HW_emp

empno ename job sal

7369 Smith Clerk 1200

7499 Allen Salesman 2000

7521 Ward Salesman 1650

7566 Jones Manager 3375

7654 Martin Salesman 1650

7698 Blake Manager 3250

7782 Clark Manager 2850

7788 Scott Analyst 3500

7839 King President 6500

7844 Turner Salesman 1900

7876 Adams Clerk 1500

7900 James Clerk 1350

7902 Ford Analyst 3500

7934 Miller Clerk 1700

WITH temp AS

(SELECT job, MAX(sal) AS maxSal

FROM HW_emp

GROUP BY job)

SELECT E1.ename

FROM HW_emp E1, temp AS T

WHERE E1.sal = T.maxSal

“Uncorrelated”

ename

Allen

Jones

Scott

King

Ford

Miller

Page 6: SQL (4): Subqueries

Subqueries in WITH

HW_emp

empno ename job sal

7369 Smith Clerk 1200

7499 Allen Salesman 2000

7521 Ward Salesman 1650

7566 Jones Manager 3375

7654 Martin Salesman 1650

7698 Blake Manager 3250

7782 Clark Manager 2850

7788 Scott Analyst 3500

7839 King President 6500

7844 Turner Salesman 1900

7876 Adams Clerk 1500

7900 James Clerk 1350

7902 Ford Analyst 3500

7934 Miller Clerk 1700

WITH temp AS

(SELECT job, MAX(sal) AS maxSal

FROM HW_emp

GROUP BY job)

SELECT E1.ename

FROM HW_emp E1, temp AS T

WHERE E1.sal = T.maxSal

ename

Allen

Jones

Scott

King

Ford

Miller

Page 7: SQL (4): Subqueries

Subqueries and Set OperationsUNION

INTERSECT

EXCEPT

(sub-result1)

(sub-result2)

UNION

(sub-result1)

(sub-result2)

INTERSECT

(sub-result1)

(sub-result2)

EXCEPT

Requirements:

UNION INTERSECT. EXCEPT

Page 8: SQL (4): Subqueries

Product(pid, name, cid)

-- cid is foreign key to Company.cid

Company(cid, cname, city)

Customer(custId, name, city)

Purchase(purchase_date, pid, custId, quantity, price)

-- pid is foreign key to Product.pid,

-- custId is foreign key to Customer.custId

Let’s Solve A Problem

Page 9: SQL (4): Subqueries

Set difference (–)

(sub-result1)

(sub-result2)

EXCEPT

EXCEPT

2

1

Let’s Solve A Problem

Page 10: SQL (4): Subqueries

EXCEPT

– =

(sub-result1) (sub-result2)

(difference)

2

1

Use EXCEPT to Solve the Problem

Page 11: SQL (4): Subqueries

Find which companies the customers have purchased.

Then, find the names of the customers

Use EXCEPT to Solve the Problem (2)

SELECT T1.custId, T2.cid

FROM Purchase T1 NATURAL JOIN Product T2

GROUP BY T1.custId, T2.cid

Got all customers who have purchased.

Still need to find the names of the customers

1

Page 12: SQL (4): Subqueries

SELECT T3.custId, T3.name

FROM (SELECT T1.custId, T2.cid

FROM Purchase T1 NATURAL JOIN Product T2

GROUP BY T1.custId, T2.cid) T

NATURAL JOIN Customer T3

Find which companies the customers have purchased

Then, find the names of the customers

1

Use EXCEPT to Solve the Problem (3)

Page 13: SQL (4): Subqueries

Find all customers who have purchased from other companies

Then, find the names of the customers

SELECT T1.custId

FROM Purchase T1 NATURAL JOIN Product T2

WHERE T2.cid <> 7777

GROUP BY T1.custId

2

Got all customers who have not purchased from 7777.

Still need to find the namesof the customers

Use EXCEPT to Solve the Problem (4)

Page 14: SQL (4): Subqueries

SELECT T3.custId, T3.name

FROM (SELECT T1.custId

FROM Purchase T1 NATURAL JOIN Product T2

WHERE T2.cid <> 7777

GROUP BY T1.custId) T

NATURAL JOIN Customer T3

Find all customers who have purchased from other companies

Then, find the names of the customers

Use EXCEPT to Solve the Problem (5)

2

Page 15: SQL (4): Subqueries

EXCEPT

(SELECT T3.custId, T3.name

FROM (SELECT T1.custId

FROM Purchase T1 NATURAL JOIN Product T2

WHERE T2.cid <> 7777

GROUP BY T1.custId) T

NATURAL JOIN Customer T3)

(SELECT T3.custId, T3.name

FROM (SELECT T1.custId, T2.cid

FROM Purchase T1 NATURAL JOIN Product T2

GROUP BY T1.custId, T2.cid) T

NATURAL JOIN Customer T3)

=

2

1

Use EXCEPT to Solve the Problem (6)

Page 16: SQL (4): Subqueries

Alternative toEXCEPT (MINUS)

16

Page 17: SQL (4): Subqueries

Here’s an example

usingLeft JoinLET ’S ASSUME WE HAVE

THESE TWO TABLES

17

Page 18: SQL (4): Subqueries

Alternative toEXCEPT (MINUS)QUESTION:

18

Page 19: SQL (4): Subqueries

Alternative toEXCEPT (MINUS)

19

SELECT t1.* FROM suppliers_1 AS t1 LEFT JOIN

suppliers_2 AS t2 ON

t1.SupplierID=t2.SupplierIDAND t1.CompanyName=t2.CompanyNameAND t1.ContactName=t2.ContactNameAND t1.ContactTitle=t2.ContactTitle

WHERE t2.SupplierID IS NULL;

Page 20: SQL (4): Subqueries

Example: UNION

(SELECT T3.custId, T3.name

FROM (SELECT T1.custId

FROM Purchase T1 NATURAL JOIN Product T2

WHERE T2.cid <> 7777

GROUP BY T1.custId) T

NATURAL JOIN Customer T3)

UNION

(SELECT T3.custId, T3.name

FROM (SELECT T1.custId, T2.cid

FROM Purchase T1 NATURAL JOIN Product T2

GROUP BY T1.custId, T2.cid) T

NATURAL JOIN Customer T3)

U

=

Page 21: SQL (4): Subqueries

Example: INTERSECT

(SELECT T3.custId, T3.name

FROM (SELECT T1.custId

FROM Purchase T1 NATURAL JOIN Product T2

WHERE T2.cid <> 7777

GROUP BY T1.custId) T

NATURAL JOIN Customer T3)

INTERSECT

(SELECT T3.custId, T3.name

FROM (SELECT T1.custId, T2.cid

FROM Purchase T1 NATURAL JOIN Product T2

GROUP BY T1.custId, T2.cid) T

NATURAL JOIN Customer T3)

=

Page 22: SQL (4): Subqueries

Alternative toINTERSECT

22

SELECT t1.* FROM suppliers_1 AS t1 JOIN

suppliers_2 AS t2 ON

t1.SupplierID=t2.SupplierIDAND t1.CompanyName=t2.CompanyNameAND t1.ContactName=t2.ContactNameAND t1.ContactTitle=t2.ContactTitle;