Download as pdf or txt
Download as pdf or txt
You are on page 1of 8

‫اﻟﻔﺼﻞ اﻟﺴﺎدس‬

‫‪Subqueries‬‬

‫هﺪف اﻟﺪر ِ‬
‫س‬

‫ﻣﻌﺮﻓﺔ اﻧﻮاع و ﻣﻤﻴﺰاتِ اﺳﺘﺨﺪام ‪ Subqueries‬ﺣﻴﺚ اﻧﻬﺎ ﺗﻌﺎﻟﺞ اﻟﻜﺜﻴﺮ ﻣﻦ اﻟﻤﺸﺎآﻞ‪.‬‬

‫ن ﺗَﻜْﺘﺐَ اﺳﺘﻌﻼم ﻓﺮﻋﻲ ﻓﻲ ﻓﻘﺮة ‪. WHERE‬‬


‫ﻦ أَ ْ‬
‫أﻧﺖَ ﻳُﻤﻜ ُ‬

‫‪----------------------------------------------------------------------------------------‬‬

‫ﻟﻨﻔﺘﺮض أﻧﻚ ﺗﺮﻳﺪ ﻣﻌﺮﻓﺔ اﻟﻤﻮﻇﻔﻴﻦ اﻟﺬﻳﻦ ﺗﺰﻳﺪ رواﺗﺒﻬﻢ ﻋﻦ اﻟﻤﻮﻇﻒ ‪. SMITH‬‬

‫ج اﻟﻰ اﺳﺘﻌﻼﻣﻴﻦ‪:‬‬
‫ﺤﻞﱠ هﺬﻩ اﻟﻤﺸﻜﻠﺔِ‪ ،‬ﺗَﺤﺘﺎ ُ‬
‫ﻰ ﺗَ ْ‬
‫ﻟﻜ ْ‬

‫‪ -1‬اﺳﺘﻌﻼم ﻹﻳﺠﺎد راﺗﺐ اﻟﻤﻮﻇﻒ ‪. SMITH‬‬

‫‪ -2‬اﺳﺘﻌﻼم ﻹﻳﺠﺎد اﻟﻤﻮﻇﻔﻴﻦ اﻟﺬﻳﻦ ﺗﺰﻳﺪ رواﺗﺒﻬﻢ ﻋﻦ اﻟﻤﺒﻠﻎ اﻟﻤﺤﺴﻮب ﻓﻲ‬


‫اﻻﺳﺘﻌﻼم اﻷول‪.‬‬

‫اﻟﺼﻴﻐﺔ اﻟﻌﺎﻣﺔ اﻻﺳﺘﻌﻼم اﻟﻔﺮﻋﻲ‬

‫ﺬ ﻗﺒﻞ اﻻﺳﺘﻌﻼم اﻟﺮّﺋﻴﺴﻲ‪.‬‬


‫* اﻻﺳﺘﻌﻼم اﻟﻔﺮﻋﻲ )اﻻﺳﺘﻌﻼم اﻟﺪاﺧﻠﻲ( ﻳُﻨﻔّ ُ‬

‫ن ﺗَﻀﻊَ اﻻﺳﺘﻌﻼﻣﺎت اﻟﻔﺮﻋﻴﺔ ﻓﻲ اآﺜﺮ ﻣﻦ ﻓﻘﺮة ﻓﻰ ﺟﻤﻠﺔ ‪ SELECT‬آﻤﺎ ﻳﻠﻰ ‪:‬‬


‫ﻦ أَ ْ‬
‫*ﻳُﻤﻜ ُ‬

‫*ﻓﻰ ﻓﻘﺮة ‪. WHERE‬‬

‫*ﻓﻰ ﻓﻘﺮة ‪. HAVING‬‬

‫* ﻓﻰ ﻓﻘﺮة ‪. FROM‬‬

‫ﻣﻼﺣﻈﺔ‪ :‬ﺷﺮوط اﻟﻤﻘﺎرﻧﺔ‪:‬‬


‫ﻣﻼﺣﻈﺔ‪:‬‬

‫اذا آﺎن اﻻﺳﺘﻌﻼم اﻟﻔﺮﻋﻰ ﻧﺘﻴﺠﺘﺔ ﻗﻴﻤﺔ واﺣﺪة ﻓﻴﻤﻜﻨﻚ اﺳﺘﺨﺪام) =< ‪( >, =, >=, <, <>,‬‬

‫اﻣﺎ اذا آﺎن اﻻﺳﺘﻌﻼم اﻟﻔﺮﻋﻰ ﻧﺘﻴﺠﺘﺔ اآﺜﺮ ﻣﻦ ﻗﻴﻤﺔ ﻓﻴﻤﻜﻨﻚ اﺳﺘﺨﺪام )‪. (IN, ANY, ALL‬‬
‫اﺳﺘﺨﺪام اﻻﺳﺘﻌﻼم اﻟﻔﺮﻋﻲ‬

‫ﻓﺎﻟﻤﺜﺎل اﻟﺴﺎﺑﻖ ﻳﺮﻳﺪ ﻋﺮض ﺑﻴﺎﻧﺎت اﻟﻤﻮﻇﻔﻴﻦ اﻟﺬﻳﻦ ﻳﺄﺧﺬون ﻣﺮﺗﺐ اآﺒﺮ ﻣﻦ اﻟﻤﻮﻇﻒ ‪Abel‬‬

‫وﻟﻜﻨﻨﺎ ﻻ ﻧﻌﺮف ﻣﺮﺗﺐ ‪ Abel‬؟‬

‫ﺗﺴﺘﺨﺪم اﻻﺳﺘﻌﻼﻣﺎت اﻟﻔﺮﻋﻴﺔ ﻟﺤﻞ ﻣﺸﻜﻠﺔ ﻣﺎ ﺑﺎﺳﺘﺨﺪام ﺟﻤﻠﺔ اﻟﺸﺮط اﻟﺘﻰ ﺗﻌﺘﻤﺪ ﻋﻠﻲ‬
‫ﺑﻴﺎﻧﺎت ﻏﻴﺮ ﻣﻌﺮوﻓﺔ ‪.‬‬

‫ﻣﺜﺎل‪ :‬ﻧﺮﻳﺪ ﻣﻌﺮﻓﺔ اﻟﻤﻮﻇﻔﻴﻦ اﻟﺬﻳﻦ ﺗﻢ ﺗﻌﻴﻨﻬﻢ ﻗﺒﻞ اﻟﻤﻮﻇﻒ ‪FORD‬‬

‫‪Select ename from EMP‬‬

‫;)'‪Where hiredate<(select hiredate from EMP where ename ='FORD‬‬


‫وﺗﻢ ﺣﻞ اﻟﻤﺜﺎل اﻟﺴﺎﺑﻖ ﺑﺠﻤﻠﺘﻴﻦ ‪SELECT‬‬

‫*‪ :Inner Query‬وﺗﻌﻨﻰ اﻻﺳﺘﻌﻼم اﻟﻔﺮﻋﻰ اﻟﺬى ﻳﻜﻮن ﻧﺘﻴﺠﺘﺔ ﺑﺎﻟﻤﺜﺎل اﻟﺴﺎﺑﻖ ﺗﺎرﻳﺦ ﺗﻌﻴﻦ‬
‫اﻟﻤﻮﻇﻒ ‪. FORD‬‬

‫*‪: Outer Query‬وﺗﻌﻨﻰ اﻻﺳﺘﻌﻼم اﻟﺮﺋﻴﺴﻰ اﻟﺬى ﻳﻘﻮم ﺑﻤﻌﺮﻓﺔ اﻟﻤﻮﻇﻔﻴﻦ اﻟﺬﻳﻦ ﺗﻢ‬
‫ﺗﻌﻴﻨﻬﻢ ﻗﺒﻞ ﺗﺎرﻳﺦ اﻟﺘﻌﻴﻦ اﻟﻨﺎﺗﺞ ﻋﻦ ‪. Inner Query‬‬

‫أي اﻻﺳﺘﻌﻼم‬ ‫‪ main query‬أو ‪outer query‬‬ ‫‪ SELECT‬اﻷوﻟﻰ ﺗﺴﻤﻲ‬ ‫وﺟﻤﻠﺔ‬


‫اﻟﺮﺋﻴﺴﻲ وﻋﻨﺪ ﺗﻨﻔﻴﺬ اﻵﻣﺮ ﻳﺘﻢ ﺗﻨﻔﻴﺬ ‪ sub query‬او ‪ Inner Query‬أوﻻ ﺛﻢ ﺗﻄﺒﻴﻖ ‪outer‬‬
‫‪query‬آﻤﺎ ﻓﻲ اﻟﻤﺜﺎل‪.‬‬

‫‪-‬ﻣﻼﺣﻈﺎت ﻋﻠﻰ اﺳﺘﺨﺪام اﻻﺳﺘﻌﻼم اﻟﻔﺮﻋﻲ‬

‫‪ -1‬ﻳﻮﺿﻊ اﻻﺳﺘﻌﻼم اﻟﻔﺮﻋﻲ )‪ (subquery‬ﺑﻴﻦ ﻗﻮﺳﻴﻦ‪.‬‬

‫‪ -2‬ﻣﻜﺎن اﻻﺳﺘﻌﻼم اﻟﻔﺮﻋﻲ )‪ (subquery‬ﻳﻤﻴﻦ ﻋﻤﻠﻴﺔ اﻟﻤﻘﺎرﻧﺔ‪.‬‬

‫‪ -3‬ﻓﻘﺮة ‪ ORDER BY‬ﻻ ﺣﺎﺟﺔ ﻟﻬﺎ ﻓﻲ اﻻﺳﺘﻌﻼم اﻟﻔﺮﻋﻲ اﻻ ﻓﻰ ‪ TOP-N‬وﺳﻮف‬


‫ﻧﺴﺘﺨﺪﻣﻬﺎ ﻓﻰ اﻟﻔﺼﻞ ‪. 12‬‬ ‫‪.‬‬

‫‪ -4‬اذا آﺎﻧﺖ ﻧﺘﻴﺠﺔ ‪ SubQuery‬اآﺜﺮ ﻣﻦ ﻗﻴﻤﺔ واﺣﺪة ﻓﻼﺑﺪ ﻣﻦ اﺳﺘﺨﺪام )‪(ANY,IN,ALL‬‬

‫ﺣﻴﺚ اﻧﺔ ﻻﻳﻤﻜﻦ ﻣﻘﺎرﻧﺔ ﻗﻴﻤﺔ واﺣﺪ ﺑﺎآﺜﺮ ﻣﻦ ﻗﻴﻤﺔ ﺑﺎﺳﺘﺨﺪام )<‪. (>=,<=,=,<>,>,‬‬

‫أﻧﻮاع اﻻﺳﺘﻌﻼﻣﺎت اﻟﻔﺮﻋﻴﺔ‪:‬‬


‫‪SINGLE ROW SUBQUERY‬‬

‫* اﺳﺘﺮﺟﺎع ﺻﻒ واﺣﺪ ﻓﻘﻂ‪.‬‬

‫* اﺳﺘﺨﺪام ﻋﻮاﻣﻞ اﻟﻤﻘﺎرﻧﺔ ﻣﻊ اﻟﺼﻔﻮف اﻷﺣﺎدﻳﺔ ‪.‬‬

‫اﻟﻤﻌﺎﻣﻼت‬

‫=‬

‫>‬

‫=>‬

‫<‬

‫=<‬

‫><‬

‫ﻣـﺜـﺎﻟـ ‪:‬‬

‫ﻋﺮض اﻟﻤﻮﻇﻔﻴﻦ اﻟﺬﻳﻦ وﻇﻴﻔﺘﻬﻢ ﻧﻔﺲ وﻇﻴﻔﺔ اﻟﻤﻮﻇﻒ ‪.141‬‬

‫اﺳﺘﺨﺪام اﻻﺳﺘﻌﻼم اﻟﻔﺮﻋﻲ أﺣﺎدﻳﺔ اﻟﺼﻒ‬ ‫‪9-6‬‬

‫وﻳﻤﻜﻦ اﺳﺘﺨﺪام ‪ Sub Query‬اآﺜﺮ ﻣﻦ ﻣﺮة آﻤﺎ ﻓﻰ اﻟﻤﺜﺎل اﻟﺘﺎﻟﻰ‪:‬‬


‫ل ﻋﻠﻲ ﺛﻼث اﺳﺘﻌﻼﻣﺎت ‪ :‬اﻻﺳﺘﻌﻼم اﻟﺨﺎرﺟﻲ واﺳﺘﻌﻼﻣﻴﻦ داﺧﻠﻴﻦ‪.‬‬
‫ﻦ اﻟﻤﺜﺎ ُ‬
‫ﻳَﺘﻀﻤّ ُ‬

‫اﻻﺳﺘﻌﻼم اﻟﺪاﺧﻠﻰ اﻻول ﻳﻨﻔﺬ اوﻻ وﻳﺨﺮج ﻟﻨﺎ اﻟﻮﻇﻴﻔﺔ ‪ST_CLERK‬‬

‫واﻻﺳﺘﻌﻼم اﻟﺪاﺧﻠﻰ اﻟﺜﺎﻧﻰ ﻳﻨﻔﺬ ﺑﻌﺪة و ﻳﺨﺮج ﻟﻨﺎ اﻟﻤﺮﺗﺐ ‪2600‬‬

‫ﺛﻢ ﺑﻌﺪ ذﻟﻚ ﻳﺘﻢ ﺗﻨﻔﻴﺬ اﻻﺳﺘﻌﻼم اﻟﺨﺎرﺟﻰ) ‪ (OUTER QUERY‬ﺑﻨﺎء ﻋﻠﻰ ﻧﺘﻴﺠﺔ‬
‫اﻻﺳﺘﻌﻼﻣﻴﻦ اﻟﺴﺎﺑﻘﻴﻦ ‪.‬‬

‫آﻠﺘﺎ اﻻﺳﺘﻌﻼﻣﺎت اﻟﺪّاﺧﻠﻴﺔ ﺗﺴﺘﺮﺟﻊ ﻗﻴﻢ واﺣﺪة ) ‪ ST_CLEARK‬و ‪ (2600‬ﻋﻠﻲ اﻟﺘﻮاﻟﻲ‬


‫وهﺬا ﻳﺴﻤﻲ اﺳﺘﻌﻼﻣﺎت ﻓﺮﻋﻴﺔ أﺣﺎدﻳﺔ اﻟﺼﻒ‪.‬وﻟﺬﻟﻚ ﺗﻢ اﺳﺘﺨﺪام )= و > (‪.‬‬

‫ﻦ أن‬
‫ﻣﻼﺣﻈﺔ‪ :‬اﻻﺳﺘﻌﻼﻣﺎت اﻟﺨﺎرﺟﻴﺔ ‪ OUTER QUERY‬واﻟﺪّاﺧﻠﻴﺔ ‪ INEER QUERY‬ﻳُﻤﻜ ُ‬
‫ﻣﻼﺣﻈﺔ‪:‬‬
‫ﺗﺤﺼﻞ ﻋﻠﻲ ﺑﻴﺎﻧﺎت ﻣﻦ ﺟﺪاول ﻣﺨﺘﻠﻔﺔِ ﻣﺜﻞ ‪:‬‬

‫‪Select ename, job from EMP‬‬

‫;)'‪Where deptno =any(select deptno from dept where dname='ACCOUNTING‬‬

‫ﻓﻔﻰ اﻟﻤﺜﺎل اﻟﺴﺎﺑﻖ آﺎﻧﺖ ﻧﺘﻴﺠﺔ ‪ SubQuery‬ﻣﻦ ﺟﺪول اﻻﻗﺴﺎم وﺗﻢ ﻣﻘﺎرﻧﺘﻬﺎ ﻣﻊ ﺑﻴﺎﻧﺎت‬
‫ﻣﻦ ﺟﺪول اﻟﻤﻮﻇﻔﻴﻦ ‪.‬‬

‫ﻳﻤﻜﻦ اﺳﺘﺨﺪام ‪ Group Functions‬ﻣﻊ ‪Subquery‬‬


‫اﺳﺘﺨﺪام ‪ HAVING‬ﻣﻊ ‪Sub query‬‬

‫ن ﺗﺴﺘﺨﺪم ﻣﻊَاﻻﺳﺘﻌﻼﻣﺎت اﻟﻔﺮﻋﻴﺔ )‪ (SubQuery‬وﻟﻴﺲ ﻓﻘﻂ‬


‫ﻦ أَ ْ‬
‫‪ -‬ﻓﻘﺮة ‪ HAVING‬ﻳُﻤﻜ ُ‬
‫ﻓﻲ اﻟﻔﻘﺮة ‪. ِWHERE‬‬

‫م ـ ث ـ ال ـ ‪:‬‬

‫أوﺟﺪ رﻗﻢ اﻟﻤﻮﻇﻒ واﺳﻤﺔ ﻟﻠﻤﻮﻇﻔﻴﻦ اﻟﺬﻳﻦ ﻳﺎﺧﺬون اﻗﻞ ﻣﺮﺗﺐ ﻓﻰ آﻞ ﻗﺴﻢ‪.‬‬

‫ﻣﺎ اﻟﺨﻄﺄ ﻓﻲ هﺬا اﻻﺳﺘﻌﻼم؟‬

‫اﻟﺨﻄﺄ هﻨﺎ ان ‪ SubQuery‬ﻳﻨﺘﺞ ﻋﻨﻬﺎ اآﺜﺮ ﻣﻦ ﻧﺘﻴﺠﺔ وﺗﻢ ﻣﻘﺎرﻧﺘﻬﺎ ﺑﺎﻟﻤﻌﺎﻣﻞ ﻳﺴﺎوى )=(‬

‫وﻟﻤﻌﺎﻟﺠﺔ ذﻟﻚ ﻳﺠﺐ اﺳﺘﺨﺪام اﻟﻔﻘﺮة ) ‪ (= ANY‬آﻤﺎ ﻳﻠﻰ‪:‬‬

‫‪Select employee_id, last_name from Employees‬‬

‫;)‪Where salary =any (select min (salary) from Employees group by department‬‬
‫‪-‬هﻞ هﺬا اﻻﺳﺘﻌﻼم ﺳﻮف ﻳﺴﺘﺮﺟﻊ ﺻﻔﻮف؟‬

‫ﻣﻼﺣﻈﺔ‪:‬‬

‫ﺳﺒﺐ اﻟﻨﺘﻴﺠﺔ اﻟﺴﺎﺑﻘﺔ ان ‪ Sub Query‬آﺎﻧﺖ ﻧﺘﻴﺠﺘﻬﺎ ‪. NULL‬‬

‫اﻻﺳﺘﻌﻼم اﻟﻔﺮﻋﻲ ﻟﻠﺼﻔﻮف اﻟﻤﺘﻌﺪد‬

‫* اﺳﺘﺮﺟﺎع أآﺜﺮ ﻣﻦ ﺻﻒ واﺣﺪ‬

‫* اﺳﺘﺨﺪام ﻣﻌﺎﻣﻼت اﻟﻤﻘﺎرﻧﺔ ﻟﻠﺼﻔﻮف اﻟﻤﺘﻌﺪدة ‪.‬‬

‫اﻟﻤﻌﺎﻣﻞ‬ ‫اﻟﻤﻌﻨﻲ‬

‫‪IN‬‬ ‫اﻟﺒﺤﺚ ﻋﻦ ﻗﻴﻤﺔ ﻣﻦ ﺑﻴﻦ ﻣﺠﻤﻮﻋﺔ ﻣﻦ اﻟﻘﻴﻢ‬

‫‪ANY‬‬ ‫ﻳﻘﺎرن ﻗﻴﻤﺔ ﺑﺎى ﻗﻴﻤﺔ ﻣﺴﺘﺮﺟﻌﺔ ﺑﻮاﺳﻄﺔ‬


‫اﻻﺳﺘﻌﻼﻣﺎت اﻟﻔﺮﻋﻴﺔ‬

‫‪ALL‬‬ ‫ﻣﻘﺎرﻧﺔ ﻗﻴﻤﺔ ﻟﻜﻞ اﻟﻘﻴﻢ اﻟﻤﺴﺘﺮﺟﻌﺔ‬

‫اﺳﺘﺨﺪام ﻣﻌﺎﻣﻞ ‪ALL‬‬

‫اﻟﻤﺜﺎل اﻟﺴﺎﺑﻖ ﻳﺮﻳﺪ ﻣﻌﺮﻓﺔ اﻟﻤﻮﻇﻔﻴﻦ اﻟﺬﻳﻦ ﻳﻘﻞ ﻣﺮﺗﺒﻬﻢ ﻋﻦ ﻣﺮﺗﺐ اﻟﻤﻮﻇﻔﻴﻦ‬

‫ﺑﻮﻇﻴﻔﺔ ‪. IT_PROG‬‬
‫ﺖ ﻣِﻦ ‪. SubQuery‬‬
‫ن اﻟﻘﻴﻢَ ﺑﻜﻞ اﻟﻘﻴﻢ اﻟﺘﻲ اﺳﺘﺮَﺟﻌ ْ‬
‫ﻣﻌﺎﻣﻞ ‪ ALL‬ﻳُﻘﺎر ُ‬

‫ﻗﻴﻤﺔ ‪ Null‬ﻓﻲ اﻻﺳﺘﻌﻼم اﻟﻔﺮﻋﻲ‬

‫ﻋﻨﺪﻣﺎ ﺗﻜﻮن ﻧﺘﻴﺠﺔ ‪ NULL = SUb Query‬ﻓﻬﺬا ﻳﻌﻨﻰ ان هﺬا اﻻﺳﺘﻌﻼم ﺗﻜﻮن ﻧﺘﻴﺠﺘﺔ‬

‫‪. NO ROWS SELECTED‬‬

‫اﻟﻤﻌﺎﻣﻞ ‪ IN‬ﻳﺴﺎوى )‪(=ANY‬‬

‫‪Select ename, job from EMP where‬‬

‫;)‪Sal in (select max (sal) from EMP group by deptno‬‬

‫اﻟﻤﺜﺎل اﻟﺴﺎﺑﻖ ﻳﺮﻳﺪ اﻻﺳﺘﻌﻼم ﻋﻦ اﻟﻤﻮﻇﻔﻴﻦ اﻟﺬﻳﻦ ﻳﺎﺧﺬون اﻋﻠﻰ ﻣﺮﺗﺐ ﺑﻜﻞ ﻗﺴﻢ‪.‬‬

‫ﻳﻤﻜﻦ اﺳﺘﺨﺪام ) ‪ (=ANY‬ﺑﺪﻻ ﻣﻦ ) ‪ ( IN‬ﻓﻰ اﻟﻤﺜﺎل اﻟﺴﺎﺑﻖ وﺗﻜﻮن ﺑﻨﻔﺲ اﻟﻨﺘﻴﺠﺔ ‪:‬‬

‫‪select ename,job from EMP where‬‬

‫;)‪sal =any(select max(sal) from EMP group by deptno‬‬

You might also like