Difference between revisions of "Subquery and JOIN"

From SQLZOO
Jump to: navigation, search
(Created page with "Converting subqueries into Join functions. <div class='ht'> <div class=params>schema:scott</div> <source lang=sql class='tidy'></source> <source lang=sql class='setup'> CREATE...")
 
(15 intermediate revisions by one user not shown)
Line 1: Line 1:
Converting subqueries into Join functions.
+
<p>Here you are shown how to convert subqueries into JOIN functions this would be done
 +
as using subqueries that contain no aggregate functions unnecessarily</p>
 +
causes the response speed of the query to slow down.
 
<div class='ht'>
 
<div class='ht'>
 
<div class=params>schema:scott</div>
 
<div class=params>schema:scott</div>
<source lang=sql class='tidy'></source>
+
<source lang=sql class='tidy'>DROP TABLE jobs;
 +
DROP TABLE ranks;
 +
DROP TABLE salary;</source>
 
<source lang=sql class='setup'> CREATE TABLE jobs(
 
<source lang=sql class='setup'> CREATE TABLE jobs(
   employee VARCHAR(40)),
+
   employee VARCHAR(40),
 
   title VARCHAR(40));
 
   title VARCHAR(40));
INSERT INTO jobs VALUES ('Gordon Russel','Lecturer');
+
INSERT INTO jobs VALUES ('Gordon Russell','Lecturer');
 
INSERT INTO jobs VALUES ('Andrew Cumming','Teaching fellow');
 
INSERT INTO jobs VALUES ('Andrew Cumming','Teaching fellow');
 
INSERT INTO jobs VALUES ('Jim Smith','Technician');
 
INSERT INTO jobs VALUES ('Jim Smith','Technician');
 
CREATE TABLE ranks (
 
CREATE TABLE ranks (
   title VARCHAR(20),
+
   title VARCHAR(40),
   rank VARCHAR(20));
+
   rank VARCHAR(40));
INSERT INTO city VALUES ('Lecturer','LECT1');
+
INSERT INTO ranks VALUES ('Lecturer','LECT1');
INSERT INTO city VALUES ('Teaching fellow','LECT2');
+
INSERT INTO ranks VALUES ('Teaching fellow','LECT2');
INSERT INTO city VALUES ('Technician','TECH1');
+
INSERT INTO ranks VALUES ('Technician','TECH1');
 
CREATE TABLE salary (
 
CREATE TABLE salary (
   rank VARCHAR(20),
+
   rank VARCHAR(40),
 
   payment INTEGER);
 
   payment INTEGER);
INSERT INTO city VALUES ('LECT1',2000.00);
+
INSERT INTO salary VALUES ('LECT1',2000);
INSERT INTO city VALUES ('LECT2',3000.00);
+
INSERT INTO salary VALUES ('LECT2',3000);
INSERT INTO city VALUES ('TECH1',5000.00);
+
INSERT INTO salary VALUES ('TECH1',5000);
INSERT INTO city VALUES ('TECH2',6000.00 );
+
INSERT INTO salary VALUES ('TECH2',6000);
 
</source>
 
</source>
 
<div>
 
<div>
 
  SELECT payment FROM salary WHERE rank =
 
  SELECT payment FROM salary WHERE rank =
(SELECT rank FROM ranks WHERE title =
+
  (SELECT rank FROM ranks WHERE title =
(SELECT title FROM jobs WHERE employee = 'Andrew Cumming'))
+
  (SELECT title FROM jobs  
This subquery would be more efficient if it was changed to a JOIN as there are no
+
    WHERE employee = 'Andrew Cumming'))
 +
This subquery would be more efficient if it was changed to a <code>JOIN</code> as there are no
 
aggregate functions in the queries.  
 
aggregate functions in the queries.  
<ul>Use the following steps to change a subquery into a JOIN
+
<ul>Use the following steps to change a subquery into a <code>JOIN</code>
 
  <li>Mark all columns with the table name they came from</li>
 
  <li>Mark all columns with the table name they came from</li>
  <li>If you use the same table in two different FROM clauses, use aliases</li>
+
  <li>If you use the same table in two different <code>FROM</code> clauses, use aliases</li>
  <li>Move all FROM statements together to form a single FROM </li>
+
  <li>Move all <code>FROM</code> statements together to form a single <code>FROM</code> </li>
  <li>Delete all occurrences of (SELECT </li>
+
  <li>Delete all occurrences of (<code>SELECT</code> </li>
  <li>Substitute WHERE for AND after the first occurence of WHERE</li>
+
  <li>Substitute <code>WHERE</code> for AND after the first occurence of <code>WHERE</code></li>
 
</ul>
 
</ul>
 
</div>
 
</div>
<source lang='sql' class='def'>SELECT payment FROM salary, ranks, jobs
+
<source lang='sql' class='def'>
WHERE salary.rank = ranks.rank
+
AND ranks.title = jobs.title
+
AND jobs.employee = 'Andrew Cumming'</source>
+
<div class="ecomm e-mysql" style="display: none">JOIN ON functions would also work with
+
 
SELECT payment  
 
SELECT payment  
FROM salary JOIN ranks ON (salary.rank = ranks.rank)
+
  FROM salary, ranks, jobs
JOIN jobs ON (ranks.title = jobs.title)
+
  WHERE salary.rank = ranks.rank
WHERE jobs.employee = 'Andrew Cumming'</div>
+
    AND ranks.title = jobs.title
 +
    AND jobs.employee = 'Andrew Cumming'</source>
 +
<div class="ecomm e-mysql" style="display: none"><code>JOIN ON</code> functions would also work with:
 +
<pre>SELECT payment
 +
  FROM salary JOIN ranks  
 +
    ON (salary.rank = ranks.rank)
 +
  JOIN jobs ON (ranks.title = jobs.title)
 +
  WHERE jobs.employee = 'Andrew Cumming'</pre></div>
 
</div>
 
</div>
{Hacks Ref}
+
{{Hacks Ref}}

Revision as of 14:13, 2 August 2012

Here you are shown how to convert subqueries into JOIN functions this would be done as using subqueries that contain no aggregate functions unnecessarily

causes the response speed of the query to slow down.

schema:scott
DROP TABLE jobs;
DROP TABLE ranks;
DROP TABLE salary;
 CREATE TABLE jobs(
  employee VARCHAR(40),
  title VARCHAR(40));
INSERT INTO jobs VALUES ('Gordon Russell','Lecturer');
INSERT INTO jobs VALUES ('Andrew Cumming','Teaching fellow');
INSERT INTO jobs VALUES ('Jim Smith','Technician');
CREATE TABLE ranks (
   title VARCHAR(40),
   rank VARCHAR(40));
INSERT INTO ranks VALUES ('Lecturer','LECT1');
INSERT INTO ranks VALUES ('Teaching fellow','LECT2');
INSERT INTO ranks VALUES ('Technician','TECH1');
CREATE TABLE salary (
   rank VARCHAR(40),
   payment INTEGER);
INSERT INTO salary VALUES ('LECT1',2000);
INSERT INTO salary VALUES ('LECT2',3000);
INSERT INTO salary VALUES ('TECH1',5000);
INSERT INTO salary VALUES ('TECH2',6000);
SELECT payment FROM salary WHERE rank =
 (SELECT rank FROM ranks WHERE title =
 (SELECT title FROM jobs 
   WHERE employee = 'Andrew Cumming'))

This subquery would be more efficient if it was changed to a JOIN as there are no aggregate functions in the queries.

    Use the following steps to change a subquery into a JOIN
  • Mark all columns with the table name they came from
  • If you use the same table in two different FROM clauses, use aliases
  • Move all FROM statements together to form a single FROM
  • Delete all occurrences of (SELECT
  • Substitute WHERE for AND after the first occurence of WHERE
SELECT payment 
  FROM salary, ranks, jobs
  WHERE salary.rank = ranks.rank
    AND ranks.title = jobs.title
    AND jobs.employee = 'Andrew Cumming'
Personal tools
Namespaces

Variants
Actions
Reference
Toolbox
Google AdSense