Skip to content

Commit f81a6b0

Browse files
committed
completed subqueries
1 parent d4978af commit f81a6b0

File tree

1 file changed

+161
-0
lines changed

1 file changed

+161
-0
lines changed

Complete SQL & Databases - ZTM/06_Advanced_SQL.sql

+161
Original file line numberDiff line numberDiff line change
@@ -698,15 +698,176 @@ FROM city
698698
WHERE countrycode='BEL' OR countrycode='TUN' OR countrycode='NL';
699699

700700

701+
/* ----------------------------------------------------------------------------------------------------------- */
701702

703+
/********************** 27) Subqueries ************************/
704+
/*
705+
Subqueries can be used in SELECT, FROM, HAVING, WHERE.
706+
707+
For HAVING and WHERE clause, subquery must return SINGLE value record.
708+
*/
702709

710+
SELECT
711+
title, price,
712+
(SELECT AVG(price) FROM products) AS "global average price"
713+
FROM products;
703714

704715

716+
-- Subquery can returns A Single Result or Row Sets
717+
SELECT
718+
title, price,
719+
(SELECT AVG(price) FROM products) AS "global average price" -- return single result
720+
FROM (
721+
SELECT * FROM products -- return row sets
722+
) AS "products_sub";
723+
724+
/************ 29) Types of Subqueries *************/
725+
/*
726+
Single Row
727+
Multiple Row
728+
Multiple Column
729+
Correlated
730+
Nested
731+
*/
732+
733+
-- Single Row: returns Zero or One Row
734+
SELECT emp_no, salary
735+
FROM salaries
736+
WHERE salary > (
737+
SELECT AVG(salary) FROM salaries
738+
);
705739

740+
-- Multiple Row: returns One or More Rows
741+
SELECT title, price, category
742+
FROM products
743+
WHERE category IN (
744+
SELECT category FROM categories
745+
WHERE categoryname IN ('Comedy', 'Family', 'Classics')
746+
);
706747

748+
-- Multiple Columns: returns ONE or More columns
749+
SELECT emp_no, salary, dea.avg AS "Department average salary"
750+
FROM salaries s
751+
JOIN dept_emp as de USING(emp_no)
752+
JOIN(
753+
SELECT dept_no, AVG(salary) FROM salaries AS s2
754+
JOIN dept_emp AS de2 USING(emp_no)
755+
GROUP BY dept_no
756+
) AS dea USING (dept_no)
757+
WHERE salary > dea.avg;
758+
759+
760+
-- Correlated: Reference ONE or More columns in the OUTER statement - Runs against Each Row
761+
/* Get the most recent salary of employee */
762+
SELECT emp_no, salary AS "most recent salary", from_date
763+
FROM salaries AS s
764+
WHERE from_date = (
765+
SELECT MAX(s2.from_date) AS max
766+
FROM salaries AS s2
767+
WHERE s2.emp_no = s.emp_no
768+
)
769+
ORDER BY emp_no;
707770

708771

772+
-- Nested : Subquery in Subquery
773+
SELECT orderlineid, prod_id, quantity
774+
FROM orderlines
775+
JOIN(
776+
SELECT prod_id
777+
FROM products
778+
WHERE category IN(
779+
SELECT category FROM categories
780+
WHERE categoryname IN('Comedy', 'Family', 'Classics')
781+
)
782+
) AS limited USING(prod_id);
709783

784+
/*************** 30) Using Subqueries ************/
785+
SELECT
786+
first_name,
787+
last_name,
788+
birth_date,
789+
AGE(birth_date)
790+
FROM employees
791+
WHERE AGE(birth_date) > (SELECT AVG(AGE(birth_date)) FROM employees);
792+
793+
794+
/* Show the salary with title of the employee using Subquery, instead of JOIN */
795+
SELECT emp_no, salary, from_date,
796+
(SELECT title FROM titles AS t
797+
WHERE t.emp_no=s.emp_no AND t.from_date=s.from_date)
798+
FROM salaries s
799+
ORDER BY emp_no;
710800

801+
EXPLAIN ANALYZE
802+
SELECT emp_no, salary AS "most recent salary", from_date
803+
FROM salaries AS s
804+
WHERE from_date = (
805+
SELECT MAX(s2.from_date) AS max
806+
FROM salaries AS s2
807+
WHERE s2.emp_no = s.emp_no
808+
)
809+
ORDER BY emp_no;
711810

712811

812+
/********************** 32) Subqueries Operators *******************/
813+
/*
814+
EXISTS : Check if the subquery returns any rows
815+
*/
816+
SELECT firstname, lastname, income
817+
FROM customers AS c
818+
WHERE EXISTS(
819+
SELECT * FROM orders as o
820+
WHERE c.customerid = o.customerid AND totalamount > 400
821+
) AND income > 90000
822+
823+
/*
824+
IN : Check if the value is equal to any of the rows in the return (NULL yields NULL)
825+
NOT IN : Check if the value is NOT equal to any of the rows in the return (NULL yields NULL)
826+
*/
827+
SELECT prod_id
828+
FROM products
829+
WHERE category IN(
830+
SELECT category FROM categories
831+
WHERE categoryname IN ('Comedy', 'Family', 'Classics')
832+
);
833+
834+
835+
SELECT prod_id
836+
FROM products
837+
WHERE category IN(
838+
SELECT category FROM categories
839+
WHERE categoryname NOT IN ('Comedy', 'Family', 'Classics')
840+
);
841+
842+
/*
843+
ANY / SOME : check each row against the operator and if any comparison matches, return TRUE.
844+
*/
845+
846+
SELECT prod_id
847+
FROM products
848+
WHERE category = ANY(
849+
SELECT category FROM categories
850+
WHERE categoryname IN ('Comedy', 'Family', 'Classics')
851+
);
852+
853+
/*
854+
ALL : check each row against the operator and if all comparisions match, return true.
855+
*/
856+
SELECT prod_id, title, sales
857+
FROM products
858+
JOIN inventory as i USING(prod_id)
859+
WHERE i.sales > ALL(
860+
SELECT AVG(sales) FROM inventory
861+
JOIN products as p1 USING(prod_id)
862+
GROUP BY p1.category
863+
);
864+
865+
/*
866+
Single Value Comparison
867+
*/
868+
SELECT prod_id
869+
FROM products
870+
WHERE category = (
871+
SELECT category FROM categories
872+
WHERE categoryname IN ('Comedy')
873+
);

0 commit comments

Comments
 (0)