@@ -698,15 +698,176 @@ FROM city
698
698
WHERE countrycode= ' BEL' OR countrycode= ' TUN' OR countrycode= ' NL' ;
699
699
700
700
701
+ /* ----------------------------------------------------------------------------------------------------------- */
701
702
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
+ */
702
709
710
+ SELECT
711
+ title, price,
712
+ (SELECT AVG (price) FROM products) AS " global average price"
713
+ FROM products;
703
714
704
715
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
+ );
705
739
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
+ );
706
747
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;
707
770
708
771
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);
709
783
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;
710
800
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;
711
810
712
811
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