Common Use Case
Often, there is a need to filter the results of a query based on the results of another query, dynamically. For example, consider the task of producing a report on a daily basis containing the most recent day’s business transactions. A user could update the query on a daily basis to contain the hardcoded value associated with the most recent date value. However, the more reliable and convenient option would be to use a subquery to return this date value at runtime.
Example Data
The schemas, corresponding tables, and data used in the example problems can be found at livesql.oracle.com. To more easily follow the examples covered on this page, consider first reading the table descriptions below and reviewing each table’s contents. To review the data maintained in each table, click on the icon next to the table name. To hide the data, click the icon again.
hr.employees
Contains information related to each employee and a hierarchal employee-manager relationship. There is one row per employee.
| employee_id | first_name | last_name | phone_number | hire_date | job_id | salary | commission_pct | manager_id | department_id | |
|---|---|---|---|---|---|---|---|---|---|---|
| 100 | Steven | King | SKING | 515.123.4567 | 17-Jun-03 | AD_PRES | 24000 | – | – | 90 |
| 101 | Neena | Kochhar | NKOCHHAR | 515.123.4568 | 21-Sep-05 | AD_VP | 17000 | – | 100 | 90 |
| 102 | Lex | De Haan | LDEHAAN | 515.123.4569 | 13-Jan-01 | AD_VP | 17000 | – | 100 | 90 |
| 103 | Alexander | Hunold | AHUNOLD | 590.423.4567 | 3-Jan-06 | IT_PROG | 9000 | – | 102 | 60 |
| 104 | Bruce | Ernst | BERNST | 590.423.4568 | 21-May-07 | IT_PROG | 6000 | – | 103 | 60 |
| 105 | David | Austin | DAUSTIN | 590.423.4569 | 25-Jun-05 | IT_PROG | 4800 | – | 103 | 60 |
| 106 | Valli | Pataballa | VPATABAL | 590.423.4560 | 5-Feb-06 | IT_PROG | 4800 | – | 103 | 60 |
| 107 | Diana | Lorentz | DLORENTZ | 590.423.5567 | 7-Feb-07 | IT_PROG | 4200 | – | 103 | 60 |
| 108 | Nancy | Greenberg | NGREENBE | 515.124.4569 | 17-Aug-02 | FI_MGR | 12008 | – | 101 | 100 |
| 109 | Daniel | Faviet | DFAVIET | 515.124.4169 | 16-Aug-02 | FI_ACCOUNT | 9000 | – | 108 | 100 |
| 110 | John | Chen | JCHEN | 515.124.4269 | 28-Sep-05 | FI_ACCOUNT | 8200 | – | 108 | 100 |
| 111 | Ismael | Sciarra | ISCIARRA | 515.124.4369 | 30-Sep-05 | FI_ACCOUNT | 7700 | – | 108 | 100 |
| 112 | Jose Manuel | Urman | JMURMAN | 515.124.4469 | 7-Mar-06 | FI_ACCOUNT | 7800 | – | 108 | 100 |
| 113 | Luis | Popp | LPOPP | 515.124.4567 | 7-Dec-07 | FI_ACCOUNT | 6900 | – | 108 | 100 |
| 114 | Den | Raphaely | DRAPHEAL | 515.127.4561 | 7-Dec-02 | PU_MAN | 11000 | – | 100 | 30 |
| 115 | Alexander | Khoo | AKHOO | 515.127.4562 | 18-May-03 | PU_CLERK | 3100 | – | 114 | 30 |
| 116 | Shelli | Baida | SBAIDA | 515.127.4563 | 24-Dec-05 | PU_CLERK | 2900 | – | 114 | 30 |
| 117 | Sigal | Tobias | STOBIAS | 515.127.4564 | 24-Jul-05 | PU_CLERK | 2800 | – | 114 | 30 |
| 118 | Guy | Himuro | GHIMURO | 515.127.4565 | 15-Nov-06 | PU_CLERK | 2600 | – | 114 | 30 |
| 119 | Karen | Colmenares | KCOLMENA | 515.127.4566 | 10-Aug-07 | PU_CLERK | 2500 | – | 114 | 30 |
| 120 | Matthew | Weiss | MWEISS | 650.123.1234 | 18-Jul-04 | ST_MAN | 8000 | – | 100 | 50 |
| 121 | Adam | Fripp | AFRIPP | 650.123.2234 | 10-Apr-05 | ST_MAN | 8200 | – | 100 | 50 |
| 122 | Payam | Kaufling | PKAUFLIN | 650.123.3234 | 1-May-03 | ST_MAN | 7900 | – | 100 | 50 |
| 123 | Shanta | Vollman | SVOLLMAN | 650.123.4234 | 10-Oct-05 | ST_MAN | 6500 | – | 100 | 50 |
| 124 | Kevin | Mourgos | KMOURGOS | 650.123.5234 | 16-Nov-07 | ST_MAN | 5800 | – | 100 | 50 |
| 125 | Julia | Nayer | JNAYER | 650.124.1214 | 16-Jul-05 | ST_CLERK | 3200 | – | 120 | 50 |
| 126 | Irene | Mikkilineni | IMIKKILI | 650.124.1224 | 28-Sep-06 | ST_CLERK | 2700 | – | 120 | 50 |
| 127 | James | Landry | JLANDRY | 650.124.1334 | 14-Jan-07 | ST_CLERK | 2400 | – | 120 | 50 |
| 128 | Steven | Markle | SMARKLE | 650.124.1434 | 8-Mar-08 | ST_CLERK | 2200 | – | 120 | 50 |
| 129 | Laura | Bissot | LBISSOT | 650.124.5234 | 20-Aug-05 | ST_CLERK | 3300 | – | 121 | 50 |
| 130 | Mozhe | Atkinson | MATKINSO | 650.124.6234 | 30-Oct-05 | ST_CLERK | 2800 | – | 121 | 50 |
| 131 | James | Marlow | JAMRLOW | 650.124.7234 | 16-Feb-05 | ST_CLERK | 2500 | – | 121 | 50 |
| 132 | TJ | Olson | TJOLSON | 650.124.8234 | 10-Apr-07 | ST_CLERK | 2100 | – | 121 | 50 |
| 133 | Jason | Mallin | JMALLIN | 650.127.1934 | 14-Jun-04 | ST_CLERK | 3300 | – | 122 | 50 |
| 134 | Michael | Rogers | MROGERS | 650.127.1834 | 26-Aug-06 | ST_CLERK | 2900 | – | 122 | 50 |
| 135 | Ki | Gee | KGEE | 650.127.1734 | 12-Dec-07 | ST_CLERK | 2400 | – | 122 | 50 |
| 136 | Hazel | Philtanker | HPHILTAN | 650.127.1634 | 6-Feb-08 | ST_CLERK | 2200 | – | 122 | 50 |
| 137 | Renske | Ladwig | RLADWIG | 650.121.1234 | 14-Jul-03 | ST_CLERK | 3600 | – | 123 | 50 |
| 138 | Stephen | Stiles | SSTILES | 650.121.2034 | 26-Oct-05 | ST_CLERK | 3200 | – | 123 | 50 |
| 139 | John | Seo | JSEO | 650.121.2019 | 12-Feb-06 | ST_CLERK | 2700 | – | 123 | 50 |
| 140 | Joshua | Patel | JPATEL | 650.121.1834 | 6-Apr-06 | ST_CLERK | 2500 | – | 123 | 50 |
| 141 | Trenna | Rajs | TRAJS | 650.121.8009 | 17-Oct-03 | ST_CLERK | 3500 | – | 124 | 50 |
| 142 | Curtis | Davies | CDAVIES | 650.121.2994 | 29-Jan-05 | ST_CLERK | 3100 | – | 124 | 50 |
| 143 | Randall | Matos | RMATOS | 650.121.2874 | 15-Mar-06 | ST_CLERK | 2600 | – | 124 | 50 |
| 144 | Peter | Vargas | PVARGAS | 650.121.2004 | 9-Jul-06 | ST_CLERK | 2500 | – | 124 | 50 |
| 145 | John | Russell | JRUSSEL | 011.44.1344.429268 | 1-Oct-04 | SA_MAN | 14000 | 0.4 | 100 | 80 |
| 146 | Karen | Partners | KPARTNER | 011.44.1344.467268 | 5-Jan-05 | SA_MAN | 13500 | 0.3 | 100 | 80 |
| 147 | Alberto | Errazuriz | AERRAZUR | 011.44.1344.429278 | 10-Mar-05 | SA_MAN | 12000 | 0.3 | 100 | 80 |
| 148 | Gerald | Cambrault | GCAMBRAU | 011.44.1344.619268 | 15-Oct-07 | SA_MAN | 11000 | 0.3 | 100 | 80 |
| 149 | Eleni | Zlotkey | EZLOTKEY | 011.44.1344.429018 | 29-Jan-08 | SA_MAN | 10500 | 0.2 | 100 | 80 |
| 150 | Peter | Tucker | PTUCKER | 011.44.1344.129268 | 30-Jan-05 | SA_REP | 10000 | 0.3 | 145 | 80 |
| 151 | David | Bernstein | DBERNSTE | 011.44.1344.345268 | 24-Mar-05 | SA_REP | 9500 | 0.25 | 145 | 80 |
| 152 | Peter | Hall | PHALL | 011.44.1344.478968 | 20-Aug-05 | SA_REP | 9000 | 0.25 | 145 | 80 |
| 153 | Christopher | Olsen | COLSEN | 011.44.1344.498718 | 30-Mar-06 | SA_REP | 8000 | 0.2 | 145 | 80 |
| 154 | Nanette | Cambrault | NCAMBRAU | 011.44.1344.987668 | 9-Dec-06 | SA_REP | 7500 | 0.2 | 145 | 80 |
| 155 | Oliver | Tuvault | OTUVAULT | 011.44.1344.486508 | 23-Nov-07 | SA_REP | 7000 | 0.15 | 145 | 80 |
| 156 | Janette | King | JKING | 011.44.1345.429268 | 30-Jan-04 | SA_REP | 10000 | 0.35 | 146 | 80 |
| 157 | Patrick | Sully | PSULLY | 011.44.1345.929268 | 4-Mar-04 | SA_REP | 9500 | 0.35 | 146 | 80 |
| 158 | Allan | McEwen | AMCEWEN | 011.44.1345.829268 | 1-Aug-04 | SA_REP | 9000 | 0.35 | 146 | 80 |
| 159 | Lindsey | Smith | LSMITH | 011.44.1345.729268 | 10-Mar-05 | SA_REP | 8000 | 0.3 | 146 | 80 |
| 160 | Louise | Doran | LDORAN | 011.44.1345.629268 | 15-Dec-05 | SA_REP | 7500 | 0.3 | 146 | 80 |
| 161 | Sarath | Sewall | SSEWALL | 011.44.1345.529268 | 3-Nov-06 | SA_REP | 7000 | 0.25 | 146 | 80 |
| 162 | Clara | Vishney | CVISHNEY | 011.44.1346.129268 | 11-Nov-05 | SA_REP | 10500 | 0.25 | 147 | 80 |
| 163 | Danielle | Greene | DGREENE | 011.44.1346.229268 | 19-Mar-07 | SA_REP | 9500 | 0.15 | 147 | 80 |
| 164 | Mattea | Marvins | MMARVINS | 011.44.1346.329268 | 24-Jan-08 | SA_REP | 7200 | 0.1 | 147 | 80 |
| 165 | David | Lee | DLEE | 011.44.1346.529268 | 23-Feb-08 | SA_REP | 6800 | 0.1 | 147 | 80 |
| 166 | Sundar | Ande | SANDE | 011.44.1346.629268 | 24-Mar-08 | SA_REP | 6400 | 0.1 | 147 | 80 |
| 167 | Amit | Banda | ABANDA | 011.44.1346.729268 | 21-Apr-08 | SA_REP | 6200 | 0.1 | 147 | 80 |
| 168 | Lisa | Ozer | LOZER | 011.44.1343.929268 | 11-Mar-05 | SA_REP | 11500 | 0.25 | 148 | 80 |
| 169 | Harrison | Bloom | HBLOOM | 011.44.1343.829268 | 23-Mar-06 | SA_REP | 10000 | 0.2 | 148 | 80 |
| 170 | Tayler | Fox | TFOX | 011.44.1343.729268 | 24-Jan-06 | SA_REP | 9600 | 0.2 | 148 | 80 |
| 171 | William | Smith | WSMITH | 011.44.1343.629268 | 23-Feb-07 | SA_REP | 7400 | 0.15 | 148 | 80 |
| 172 | Elizabeth | Bates | EBATES | 011.44.1343.529268 | 24-Mar-07 | SA_REP | 7300 | 0.15 | 148 | 80 |
| 173 | Sundita | Kumar | SKUMAR | 011.44.1343.329268 | 21-Apr-08 | SA_REP | 6100 | 0.1 | 148 | 80 |
| 174 | Ellen | Abel | EABEL | 011.44.1644.429267 | 11-May-04 | SA_REP | 11000 | 0.3 | 149 | 80 |
| 175 | Alyssa | Hutton | AHUTTON | 011.44.1644.429266 | 19-Mar-05 | SA_REP | 8800 | 0.25 | 149 | 80 |
| 176 | Jonathon | Taylor | JTAYLOR | 011.44.1644.429265 | 24-Mar-06 | SA_REP | 8600 | 0.2 | 149 | 80 |
| 177 | Jack | Livingston | JLIVINGS | 011.44.1644.429264 | 23-Apr-06 | SA_REP | 8400 | 0.2 | 149 | 80 |
| 178 | Kimberely | Grant | KGRANT | 011.44.1644.429263 | 24-May-07 | SA_REP | 7000 | 0.15 | 149 | – |
| 179 | Charles | Johnson | CJOHNSON | 011.44.1644.429262 | 4-Jan-08 | SA_REP | 6200 | 0.1 | 149 | 80 |
| 180 | Winston | Taylor | WTAYLOR | 650.507.9876 | 24-Jan-06 | SH_CLERK | 3200 | – | 120 | 50 |
| 181 | Jean | Fleaur | JFLEAUR | 650.507.9877 | 23-Feb-06 | SH_CLERK | 3100 | – | 120 | 50 |
| 182 | Martha | Sullivan | MSULLIVA | 650.507.9878 | 21-Jun-07 | SH_CLERK | 2500 | – | 120 | 50 |
| 183 | Girard | Geoni | GGEONI | 650.507.9879 | 3-Feb-08 | SH_CLERK | 2800 | – | 120 | 50 |
| 184 | Nandita | Sarchand | NSARCHAN | 650.509.1876 | 27-Jan-04 | SH_CLERK | 4200 | – | 121 | 50 |
| 185 | Alexis | Bull | ABULL | 650.509.2876 | 20-Feb-05 | SH_CLERK | 4100 | – | 121 | 50 |
| 186 | Julia | Dellinger | JDELLING | 650.509.3876 | 24-Jun-06 | SH_CLERK | 3400 | – | 121 | 50 |
| 187 | Anthony | Cabrio | ACABRIO | 650.509.4876 | 7-Feb-07 | SH_CLERK | 3000 | – | 121 | 50 |
| 188 | Kelly | Chung | KCHUNG | 650.505.1876 | 14-Jun-05 | SH_CLERK | 3800 | – | 122 | 50 |
| 189 | Jennifer | Dilly | JDILLY | 650.505.2876 | 13-Aug-05 | SH_CLERK | 3600 | – | 122 | 50 |
| 190 | Timothy | Gates | TGATES | 650.505.3876 | 11-Jul-06 | SH_CLERK | 2900 | – | 122 | 50 |
| 191 | Randall | Perkins | RPERKINS | 650.505.4876 | 19-Dec-07 | SH_CLERK | 2500 | – | 122 | 50 |
| 192 | Sarah | Bell | SBELL | 650.501.1876 | 4-Feb-04 | SH_CLERK | 4000 | – | 123 | 50 |
| 193 | Britney | Everett | BEVERETT | 650.501.2876 | 3-Mar-05 | SH_CLERK | 3900 | – | 123 | 50 |
| 194 | Samuel | McCain | SMCCAIN | 650.501.3876 | 1-Jul-06 | SH_CLERK | 3200 | – | 123 | 50 |
| 195 | Vance | Jones | VJONES | 650.501.4876 | 17-Mar-07 | SH_CLERK | 2800 | – | 123 | 50 |
| 196 | Alana | Walsh | AWALSH | 650.507.9811 | 24-Apr-06 | SH_CLERK | 3100 | – | 124 | 50 |
| 197 | Kevin | Feeney | KFEENEY | 650.507.9822 | 23-May-06 | SH_CLERK | 3000 | – | 124 | 50 |
| 198 | Donald | OConnell | DOCONNEL | 650.507.9833 | 21-Jun-07 | SH_CLERK | 2600 | – | 124 | 50 |
| 199 | Douglas | Grant | DGRANT | 650.507.9844 | 13-Jan-08 | SH_CLERK | 2600 | – | 124 | 50 |
| 200 | Jennifer | Whalen | JWHALEN | 515.123.4444 | 17-Sep-03 | AD_ASST | 4400 | – | 101 | 10 |
| 201 | Michael | Hartstein | MHARTSTE | 515.123.5555 | 17-Feb-04 | MK_MAN | 13000 | – | 100 | 20 |
| 202 | Pat | Fay | PFAY | 603.123.6666 | 17-Aug-05 | MK_REP | 6000 | – | 201 | 20 |
| 203 | Susan | Mavris | SMAVRIS | 515.123.7777 | 7-Jun-02 | HR_REP | 6500 | – | 101 | 40 |
| 204 | Hermann | Baer | HBAER | 515.123.8888 | 7-Jun-02 | PR_REP | 10000 | – | 101 | 70 |
| 205 | Shelley | Higgins | SHIGGINS | 515.123.8080 | 7-Jun-02 | AC_MGR | 12008 | – | 101 | 110 |
| 206 | William | Gietz | WGIETZ | 515.123.8181 | 7-Jun-02 | AC_ACCOUNT | 8300 | – | 205 | 110 |
hr.jobs
Contains information related to each job. It’s possible for a job to exist without being assigned to any employee. There is one row per job.
| job_id | job_title | min_salary | max_salary |
|---|---|---|---|
| AD_PRES | President | 20080 | 40000 |
| AD_VP | Administration Vice President | 15000 | 30000 |
| AD_ASST | Administration Assistant | 3000 | 6000 |
| FI_MGR | Finance Manager | 8200 | 16000 |
| FI_ACCOUNT | Accountant | 4200 | 9000 |
| AC_MGR | Accounting Manager | 8200 | 16000 |
| AC_ACCOUNT | Public Accountant | 4200 | 9000 |
| SA_MAN | Sales Manager | 10000 | 20080 |
| SA_REP | Sales Representative | 6000 | 12008 |
| PU_MAN | Purchasing Manager | 8000 | 15000 |
| PU_CLERK | Purchasing Clerk | 2500 | 5500 |
| ST_MAN | Stock Manager | 5500 | 8500 |
| ST_CLERK | Stock Clerk | 2008 | 5000 |
| SH_CLERK | Shipping Clerk | 2500 | 5500 |
| IT_PROG | Programmer | 4000 | 10000 |
| MK_MAN | Marketing Manager | 9000 | 15000 |
| MK_REP | Marketing Representative | 4000 | 9000 |
| HR_REP | Human Resources Representative | 4000 | 9000 |
| PR_REP | Public Relations Representative | 4500 | 10500 |
Real-world Examples
In practice, subqueries in the WHERE clause are typically used to implement dynamic filter criteria. Explore the following two real-world examples to obtain a better understanding on how this type of subquery can be used.
Most Recent Employee(s) Hired
Imagine you work within a human resource department and a recurring task is to generate a report to review the information related to the most recent employee(s) hired. Instead of retrieving the entire employee listing and associated details, sorting by hire date in descending order, and then excluding all employees with a hire date less than the most recent hire date value, a subquery in the WHERE clause can be used to first determine the hire date associated with the most recent employee(s) hired and subsequently compare the value to each employee’s hire date. It’s important to note this date value is computed at query runtime and reflects the most recent hire date based on the data available at that point in time. By using the subquery, many steps and the hardcoding of date values can be avoided. See the query and corresponding result set below.
SELECT
hr.employees.employee_id,
hr.employees.first_name,
hr.employees.last_name,
hr.employees.job_id,
hr.employees.hire_date,
hr.employees.salary
FROM
hr.employees
WHERE
hr.employees.hire_date = (
SELECT
MAX(hr.employees.hire_date)
FROM
hr.employees
);
| employee_id | first_name | last_name | job_id | hire_date | salary |
|---|---|---|---|---|---|
| 167 | Amit | Banda | SA_REP | 2008-04-21 | 6200 |
| 173 | Sundita | Kumar | SA_REP | 2008-04-21 | 6100 |
Maxed Out Salary
For managers of employees, it’s important to understand where each employee sits in their current job ID’s salary range. Does the employee have room to grow or has the employee reached the maximum salary possible for the specific job ID? Imagine you’re a manager and your task is to answer this question for all employees with the ultimate goal being to generate a report containing the employee ID, job ID, and salary for each employee that has a salary equal to the maximum salary for the job ID. There are many ways to solve this problem, including the arguably more straightforward method utilizing an INNER JOIN; however, I’ve used a correlated subquery in the WHERE clause below to maintain focus on the current topic of subqueries. See the query and corresponding result set below. A brief explanation is provided following the result set.
SELECT
hr.employees.employee_id,
hr.employees.job_id,
hr.employees.salary
FROM
hr.employees
WHERE
hr.employees.salary - (
SELECT
hr.jobs.max_salary
FROM
hr.jobs
WHERE
hr.employees.job_id = hr.jobs.job_id
) = 0
| employee_id | job_id | salary |
|---|---|---|
| 109 | FI_ACCOUNT | 9000 |
In the query above, the difference between each employee’s salary and the maximum salary for their corresponding job ID is computed and compared to the value of 0 (i.e., no difference). Computing the difference is made possible by the subquery in the WHERE clause. This subquery executes one time per row in the outer query (i.e., employee) and returns the maximum salary for the specific employee’s job ID. It’s important to note the WHERE clause within the subquery ensures the correct maximum salary value from the jobs table is used to compute each difference.
Knowledge Check
If you’d like to confirm your understanding on the use of subqueries in the WHERE clause and other fundamental concepts, consider solving a handful of my practice problems here.