الاستعلامات الفرعية المتداخلة والمرتبطة في SQL، المسند موجود. استخدام استعلامات عامل التشغيل EXISTS باستخدام الدالة الموجودة

أين يوجد

يتم التحقق من الاستعلام الفرعي لوجود صف واحد أو أكثر. إذا تطابق صف واحد على الأقل مع الاستعلام، فسيتم إرجاع القيمة المنطقية TRUE. عند تحديد الكلمة الأساسية NOT الاختيارية، يتم إرجاع القيمة المنطقية TRUE إذا لم يُرجع الاستعلام الفرعي أي صفوف متطابقة.

استعلام فرعي

واستنادًا إلى الاستعلام الفرعي الذي تم تكوينه بالكامل، يتم استرداد مجموعة البيانات الناتجة.

قواعد عامة

يقوم عامل التشغيل EXISTS باختبار وجود صف واحد أو أكثر في استعلام فرعي للاستعلام الأصلي.

اختر * من الوظائف غير الموجودة (اختر * من الموظف حيث jobs.job_id=employye.job_id)؛

يقوم هذا المثال بالتحقق من الاستعلام الفرعي للسجلات باستخدام الكلمة الأساسية NOT الإضافية. يبحث المثال التالي عن سجلات محددة في استعلام فرعي لاسترداد مجموعة النتائج الرئيسية.

حدد au_lname من المؤلفين حيثما يوجد (SELECT * من الناشرين حيث Authors.city=publishers.city);

يعرض هذا الاستعلام الأسماء الأخيرة للمؤلفين (au_lname) الذين يعيشون في نفس مدينة الناشرين. لاحظ أنه يمكنك استخدام علامة النجمة في الاستعلام الفرعي لأنه يجب أن يقوم الاستعلام الفرعي بإرجاع سجل واحد فقط بالقيمة المنطقية TRUE. في مثل هذه الحالات، الأعمدة لا يهم. النقطة الأساسية هي وجود السلسلة.

في العديد من الاستعلامات، يقوم عامل التشغيل EXISTS بتنفيذ نفس الوظيفة التي يقوم بها ANY. عادةً ما يكون عامل التشغيل EXISTS أكثر كفاءة عند استخدامه مع الاستعلامات المرتبطة.

عامل التشغيل EXISTS يعادل لغويًا عامل التشغيل ANY.

عادةً ما يقوم الاستعلام الفرعي الموجود في عبارة EXISTS بتنفيذ أحد نوعين من عمليات البحث. الخيار الأول هو استخدام حرف بدل - علامة النجمة (على سبيل المثال، SELECT * FROM...)، وفي هذه الحالة لن تقوم باسترداد أي عمود أو قيمة محددة. النجمة هنا تعني "أي عمود". الخيار الثاني هو تحديد عمود محدد واحد فقط في الاستعلام الفرعي (على سبيل المثال، SELECT aujd FROM). تسمح بعض الأنظمة الأساسية الفردية باستعلامات فرعية على أعمدة متعددة (على سبيل المثال، SELECT aujd، aujname FROM...). ومع ذلك، هذه الميزة نادرة ويجب تجنبها في التعليمات البرمجية التي يجب نقلها إلى منصات أخرى.

الاختلافات بين المنصات

تدعم جميع الأنظمة الأساسية عامل التشغيل EXISTS بالشكل الذي وصفناه أعلاه.

"كان الأمر أسهل من قبل" - فكرت بينما جلست لتحسين الاستعلام التالي في SQL استوديو الإدارة. عندما كتبت ضمن MySQL، كان كل شيء أبسط حقًا - إما أنه يعمل أو لا يعمل. إما أنه يتباطأ أو لا. شرح حل جميع مشاكلي، ولم يكن هناك حاجة إلى أي شيء أكثر من ذلك. لدي الآن بيئة قوية لتطوير الاستعلامات والإجراءات/الوظائف وتصحيح الأخطاء وتحسينها، وكل هذه الفوضى لا تؤدي إلا إلى خلق المزيد من المشاكل في رأيي. ولماذا كل ذلك؟ لأن مُحسِّن الاستعلام المدمج شرير. إذا كنت أكتب في MySQL وPostgreSQL

حدد * من a، b، c حيث a.id = b.id، b.id = c.id

وسيحتوي كل جهاز لوحي على 5 آلاف سطر على الأقل - وسيتجمد كل شيء. والحمد لله! لأنه بخلاف ذلك يصاب المطور في أحسن الأحوال بالكسل عن الكتابة بشكل صحيح، وفي أسوأها لا يفهم ما يفعله على الإطلاق! بعد كل شيء، نفس الاستعلام في MSSQL سيعمل بالمثل

حدد * من a join b على a.id = b.id join c on b.id = c.id

سيقوم المُحسِّن المدمج بتمشيط الطلب الزائد وسيكون كل شيء على ما يرام.

سيقرر أيضًا بنفسه ما هو الأفضل فعله - الوجود أو الانضمام وغير ذلك الكثير. وكل شيء سوف يعمل على النحو الأمثل قدر الإمكان.

هناك واحد فقط ولكن. عند نقطة واحدة، سوف يتعثر المحسن استعلام معقدويمر، وبعد ذلك تحصل على مشكلة كبيرة. وقد لا تحصل عليه على الفور، ولكن عندما يصل وزن الجداول إلى الكتلة الحرجة.

إذن هذا هو جوهر المقال. موجودة وفيها عمليات ثقيلة جداً. هذا هو في الواقع استعلام فرعي منفصل لكلخطوط النتيجة وإذا كان هناك أيضًا تعشيش، فعادةً ما يتم إطفاء الأنوار. سيكون كل شيء على ما يرام عند إرجاع 1، 10، 50 سطرًا. لن تشعر بالفرق، وربما يكون الانضمام أبطأ. ولكن عندما يتم سحب 500، تبدأ المشاكل. 500 استعلام فرعي ضمن طلب واحد جدي.

على الرغم من أنه من وجهة نظر الفهم البشري، فإن الموجود أفضل، ولكن من وجهة نظر تكاليف الوقت للاستعلامات التي تعيد أكثر من 50 صفًا، فهي غير مقبولة.

من الضروري إجراء حجز، بطبيعة الحال، إذا انخفض في مكان ما، فيجب أن يصل إلى مكان ما. نعم، يعد الانضمام أكثر استهلاكًا للذاكرة، لأن الاحتفاظ بجدول القيم بالكامل مرة واحدة والتعامل معه أكثر تكلفة من تشغيل الاستعلامات الفرعية لكل صف، مما يؤدي إلى تحرير الذاكرة بسرعة. أنت بحاجة إلى إلقاء نظرة على الطلب على وجه التحديد وقياس ما إذا كان استخدام الذاكرة الإضافية من أجل الوقت سيكون بالغ الأهمية أم لا.

سأقدم أمثلة على القياسات الكاملة. بشكل عام، لم أواجه بعد استعلامات بهذه الدرجة من التعقيد التي لا يمكن توسيعها إلى سلسلة من الصلات. قد يستغرق الأمر يومًا، ولكن يمكن الكشف عن كل شيء.

حدد * من حيث a.id في (اختر معرفًا من b) حدد * من a حيث يوجد (اختر أعلى 1 1 من b حيث b.id = a.id) حدد * من صلة b على a.id = b. المعرف حدد * من حيث a.id ليس موجودًا (حدد المعرف من b) حدد * من a حيث لا يوجد (اختر أعلى 1 1 من b حيث b.id = a.id) حدد * من الرابط الأيسر b على a. id = b.id حيث b.id فارغ

أكرر - يقوم مُحسِّن MSSQL بتحسين هذه الأمثلة الاداء العاليولن يكون هناك أبدًا أشخاص أغبياء لديهم مثل هذه الطلبات البسيطة.

لنفكر الآن في مثال لاستعلام حقيقي كان لا بد من إعادة كتابته لأنه تجمد ببساطة في بعض العينات (البنية مبسطة للغاية وتم استبدال المفاهيم، ليست هناك حاجة للخوف من بعض عدم تحسين بنية قاعدة البيانات ).

تحتاج إلى سحب جميع "المنتجات" المكررة في حسابات مختلفة، مع التركيز على معلمات المنتج ومجموعته والمجموعة الرئيسية، إذا كانت هناك واحدة.

حدد d.PRODUCT_ID من PRODUCT s، PRODUCT_GROUP sg يسارًا، ينضم M_PG_DEPENDENCY sd على (sg.PRODUCT_GROUP_ID = sd.M_PG_DEPENDENCY_CHILD_ID)، PRODUCT d، PRODUCT_GROUP dg يسارًا ينضم M_PG_DEPENDENCY dd على (dg.PRODUCT_GROUP_ID) = dd .M_PG_DEPENDENCY_CHILD_ID) حيث s.PRODUCT_GROUP_ID=sg .PRODUCT_GROUP_ID وd.PRODUCT_GROUP_ID=dg.PRODUCT_GROUP_ID وsg.PRODUCT_GROUP_PERSPEC=dg.PRODUCT_GROUP_PERSPEC وsg.PRODUCT_GROUP_NAME=dg.PRODUCT_GROUP_NAME وs.PRODUCT_NAME=d.PRODUCT_NAME وs. PRODUCT_TYPE=d.PRODUCT_TYPE وs.PRODUCT_IS_SECURE=d.PRODUCT_IS_SECURE وs.PRODUCT_MULTISELECT=d.PRODUCT_MULTISELECT وdg.PRODUCT_GROUP_IS_TMPL=0 و ((sd.M_PG_DEPENDENCY_CHILD_ID فارغ وdd.M_PG_DEPENDENCY_CHILD_ID فارغ) أو موجود (حدد 1 من PRODUCT_GROUP sg1، PRODUCT_GROUP dg1) حيث sd.M_PG_DEPENDENCY_PARENT_ID = sg1.PRODUCT_GROUP_ID وdd .M_PG_DEPENDENCY_PARENT_ID = dg1.PRODUCT_GROUP_ID وsg1.PRODUCT_GROUP_PERSPEC=dg1.PRODUCT_GROUP_PERSPEC وsg1.PRODUCT_GROUP_NAME=dg1.PRODUCT_GROUP_NAME و))

لذلك هذا هو الحال عندما استسلم المحسن. ولكل سطر تم تنفيذ أمر ثقيل، مما أدى إلى قتل قاعدة البيانات.

حدد d.PRODUCT_ID من PRODUCT وانضم إلى PRODUCT d في s.PRODUCT_TYPE=d.PRODUCT_TYPE وs.PRODUCT_NAME=d.PRODUCT_NAME وs.PRODUCT_IS_SECURE=d.PRODUCT_IS_SECURE وs.PRODUCT_MULTISELECT=d.PRODUCT_MULTISELECT انضم إلى PRODUCT_GROUP sg s.PRODUCT_GROUP_ID= sg.PRODUCT_GROUP_ID انضم إلى PRODUCT_GROUP dg على d.PRODUCT_GROUP_ID=dg.PRODUCT_GROUP_ID وsg.PRODUCT_GROUP_NAME=dg.PRODUCT_GROUP_NAME وsg.PRODUCT_GROUP_PERSPEC=dg.PRODUCT_GROUP_PERSPEC غادرا الانضمام إلى M_PG_DEPEND E NCY sd على sg.PRODUCT_GROUP_ID = sd.M_PG_DEPENDENCY_CHILD_ID انضم إلى اليسار M_PG_DEPENDENCY dd على dg. PRODUCT_GROUP_ID = dd.M_PG_DEPENDENCY_CHILD_ID اليسار للانضمام إلى PRODUCT_GROUP sgp على sgp.PRODUCT_GROUP_ID = sd.M_PG_DEPENDENCY_PARENT_ID اليسار للانضمام إلى PRODUCT_GROUP dgp على dgp.PRODUCT_GROUP_ID = dd.M_PG_DEPENDENCY_ PARENT_ID وsgp.PRODUC T_GROUP_NAME = dgp.PRODUCT_GROUP_NAME وisnull(sgp.PRODUCT_GROUP_IS_TMPL, 0) = isnull( dgp.PRODUCT_GROUP_IS_TMPL, 0) حيث (sd.M_PG_DEPENDENCY_CHILD_ID فارغ وdd.M_PG_DEPENDENCY_CHILD_ID فارغ) أو (sgp.PRODUCT_GROUP_NAME ليس خاليًا وdgp.PRODUCT_GROUP_NAME ليس خاليًا) اذهب

بعد هذه التحولات، زاد أداء العرض بشكل كبير مع عدد المنتجات التي تم العثور عليها. أو بالأحرى، ظل وقت البحث مستقلاً عمليًا عن عدد التطابقات وكان دائمًا صغيرًا جدًا. كما ينبغي أن يكون.

هذا مثال واضح على كيف يمكن للثقة في مُحسِّن MSSQL أن تلعب مزحة قاسية. لا تثق به، لا تكن كسولًا، انضم يدويًا، وفكر في كل مرة ما هو الأفضل في موقف معين - موجود أو موجود أو انضم.

يقوم مسند لغة SQL EXISTS بتنفيذ مهمة منطقية. في استعلامات SQLويستخدم هذا المسند في تعبيرات النموذج

موجود (اختر * من TABLE_NAME ...).

يُرجع هذا التعبير صحيحًا عندما يعثر الاستعلام على صف واحد أو أكثر يطابق الشرط، ويُرجع خطأ عندما لا يتم العثور على أي صفوف.

لعدم وجود الأمر هو العكس. تعبير

غير موجود (اختر * من TABLE_NAME ...)

إرجاع صحيح عند عدم العثور على صفوف في الاستعلام، وإرجاع خطأ عند العثور على صف واحد على الأقل.

أبسط الاستعلامات مع مسند SQL EXISTS

في الأمثلة، نعمل مع قاعدة بيانات المكتبة وجداول "الكتاب قيد الاستخدام" (BOOKINUSE) و"المستخدم" (USER). في الوقت الحالي، نحتاج فقط إلى جدول "الكتاب قيد الاستخدام" (BOOKINUSE).

مؤلفعنوانسنة النشررقم الفاتورةمعرف المستخدم
تولستويالحرب و السلام2005 28 65
تشيخوفبستان الكرز2000 17 31
تشيخوفقصص مختارة2011 19 120
تشيخوفبستان الكرز1991 5 65
إيلف وبيتروفالكراسي الاثني عشر1985 3 31
ماياكوفسكيقصائد1983 2 120
الجزر الأبيضدكتور زيفاجو2006 69 120
تولستويالأحد2006 77 47
تولستويانا كارينينا1989 7 205
بوشكينابنة الكابتن2004 25 47
غوغوليلعب2007 81 47
تشيخوفقصص مختارة1987 4 205
الجزر الأبيضالمفضلة2000 137 18

مثال 1.تحديد معرفات المستخدمين الذين حصلوا على كتب تولستوي والذين حصلوا أيضًا على كتب تشيخوف. يختار الاستعلام الخارجي بيانات حول المستخدمين الذين حصلوا على كتب تولستوي، ويحدد المسند الموجود شرطًا إضافيًا يتم التحقق منه في الاستعلام الداخلي - المستخدمون الذين حصلوا على كتب تشيخوف. هناك شرط إضافي في الطلب الداخلي وهو أن تتطابق معرفات المستخدم من الطلبات الخارجية والداخلية مع: User_ID=tols_user.user_id. الطلب سيكون كالتالي:

سيعود هذا الاستعلام بالنتيجة التالية:

الاختلافات بين المسندات الموجودة والمسندات

للوهلة الأولى عند الاستعلامات التي تحتوي على المسند EXISTS، قد يكون لديك انطباع بأنها متطابقة المسند في. هذا خطأ. على الرغم من أنها متشابهة جدا. يبحث المسند IN عن قيم من النطاق المحدد في وسيطته، وإذا كانت هناك مثل هذه القيم، فسيتم تحديد جميع الصفوف المقابلة لهذا النطاق. نتيجة المسند EXISTS هي إجابة "نعم" أو "لا" على سؤال ما إذا كانت هناك أية قيم على الإطلاق تتوافق مع تلك المحددة في الوسيطة. بالإضافة إلى ذلك، يُسبق المسند IN باسم العمود الذي يتم من خلاله البحث عن الصفوف التي تطابق القيم الموجودة في النطاق. دعونا نلقي نظرة على مثال يوضح الفرق بين المسند EXISTS والمسند IN، وتم حل المشكلة باستخدام المسند IN.

مثال 4.تحديد هويات المستخدمين الذين تم إصدار كتب لهم من قبل المؤلفين الذين تم إصدار كتبهم للمستخدم بالمعرف 31. وسيكون الطلب على النحو التالي:

معرف المستخدم
120
65
205

استعلام داخلي (بعد IN) يحدد المؤلفين: تشيخوف؛ إيلف وبيتروف. يحدد الاستعلام الخارجي جميع المستخدمين الذين تم إصدار كتب لهم بواسطة هؤلاء المؤلفين. نرى أنه، على عكس المسند الموجود، فإن المسند IN يسبقه اسم العمود، في هذه الحالة - المؤلف.

الاستعلامات ذات المسند EXISTS والشروط الإضافية

إذا قمت، بالإضافة إلى مسند EXISTS في الاستعلام، بتطبيق شرط إضافي واحد على الأقل، على سبيل المثال، تم تحديده باستخدام وظائف مجمعة، فيمكن أن تعمل مثل هذه الاستعلامات على تحليل البيانات البسيطة. دعونا نوضح ذلك بالمثال التالي.

مثال 5.تحديد هويات المستخدمين الذين صدر لهم كتاب واحد على الأقل من باسترناك، والذين صدر لهم أكثر من كتابين. نكتب الاستعلام التالي، حيث يتم تحديد الشرط الأول بواسطة المسند EXISTS باستخدام استعلام متداخل، ويجب أن يأتي الشرط الثاني باستخدام عامل التشغيل HAVING دائمًا بعد الاستعلام المتداخل:

نتيجة الطلب:

معرف المستخدم
120

كما يتبين من جدول BOOKINUSE، تم أيضًا إصدار كتاب باسترناك للمستخدم بالمعرف 18، لكنه حصل على كتاب واحد فقط ولم يتم تضمينه في العينة. إذا قمت بتطبيق الدالة COUNT على استعلام مماثل مرة أخرى، ولكن هذه المرة لحساب الصفوف المحددة (تدرب على ذلك بنفسك)، فيمكنك الحصول على معلومات حول عدد المستخدمين الذين قرأوا كتب باسترناك وقرأوا أيضًا كتبًا لمؤلفين آخرين. وهذا بالفعل من مجال تحليل البيانات.

تعتمد الاستعلامات التي تحتوي على EXISTS على جدولين

يمكن للاستعلامات ذات المسند EXISTS استرداد البيانات من أكثر من جدول واحد. يمكن حل العديد من المشاكل بنفس النتيجة باستخدام انضم إلى المشغل، ولكن في بعض الحالات، يتيح لك استخدام EXISTS إنشاء استعلام أقل تعقيدًا. يفضل استخدام EXISTS في الحالات التي يحتوي فيها الجدول الناتج على أعمدة من جدول واحد فقط.

في المثال التالي، من نفس قاعدة البيانات، بالإضافة إلى جدول BOOKINUSE، ستحتاج أيضًا إلى جدول USER.

ستكون نتيجة الاستعلام الجدول التالي:

مؤلف
تشيخوف
ماياكوفسكي
الجزر الأبيض

كما هو الحال مع استخدام عامل JOIN، في الحالات التي يوجد فيها أكثر من جدول، يجب عليك استخدام الأسماء المستعارة للجدول للتأكد من تطابق قيم المفاتيح التي تربط الجداول. في مثالنا، الأسماء المستعارة للجدول هي bk وus، والمفتاح الذي يربط الجداول هو User_ID.

موجود في صلات أكثر من جدولين

سنرى الآن بمزيد من التفصيل سبب تفضيل استخدام EXISTS في الحالات التي يحتوي فيها الجدول الناتج على أعمدة من جدول واحد فقط.

نحن نعمل مع قاعدة بيانات "العقارات". يحتوي جدول الصفقات على بيانات حول الصفقات. بالنسبة لمهامنا، سيكون عمود "النوع" الذي يحتوي على بيانات حول نوع المعاملة - بيع أو إيجار - مهمًا في هذا الجدول. يحتوي جدول الكائنات على بيانات حول الكائنات. سنحتاج في هذا الجدول إلى قيم الغرف (عدد الغرف) وأعمدة LogBalc التي تحتوي على بيانات عن وجود لوجيا أو شرفة بتنسيق منطقي: 1 (نعم) أو 0 (لا). تحتوي جداول العميل والمدير والمالك على بيانات حول العملاء ومديري الشركات وأصحاب العقارات، على التوالي. في هذه الجداول، FName وLName هما الاسمان الأول والأخير، على التوالي.

مثال 7.حدد العملاء الذين اشتروا أو استأجروا عقارات لا تحتوي على لوجيا أو شرفة. نكتب الاستعلام التالي، حيث يحدد المسند EXISTS إمكانية الوصول إلى نتيجة الانضمام إلى جدولين:

نظرًا لأنه تم تحديد الأعمدة من جدول العميل باستخدام عامل تشغيل العلامة النجمية، فسيتم عرض جميع أعمدة هذا الجدول، والتي ستحتوي على عدد من الصفوف يساوي عدد العملاء الذين يطابقون الشرط المحدد بواسطة المسند الموجود. لا نحتاج إلى إخراج أي أعمدة من الجداول التي يمكن الوصول إلى صلاتها عن طريق الاستعلام الفرعي. ولذلك، لتوفير وقت الجهاز، يتم استرداد عمود واحد فقط. للقيام بذلك، يتم كتابة وحدة بعد كلمة SELECT. يتم استخدام نفس الأسلوب في الاستعلامات في الأمثلة التالية.

اكتب استعلام SQL باستخدام المسند EXISTS بنفسك، ثم انظر إلى الحل

نستمر في كتابة استعلامات SQL مع المسند EXISTS

مثال 9.تحديد أصحاب الأشياء التي تم تأجيرها. نكتب الاستعلام التالي، حيث يحدد المسند EXISTS أيضًا الوصول إلى نتيجة الانضمام إلى جدولين:

كما في المثال السابق، سيتم إرجاع كافة الحقول من الجدول الذي تم الوصول إليه بواسطة الاستعلام الخارجي.

مثال 10.تحديد عدد المالكين الذين تم التعامل مع ممتلكاتهم من قبل المدير سافيليف. نكتب استعلامًا يصل فيه الاستعلام الخارجي إلى ثلاثة جداول، ويحدد المسند EXISTS الوصول إلى جدول واحد فقط:

يتم فحص جميع الاستعلامات مقابل قاعدة بيانات موجودة. الاستخدام الناجح!

قواعد البيانات العلائقية ولغة SQL

أكاديمية نوفوسيبيرسك الحكومية للاقتصاد والإدارة

التدريب العملي على الانضباط

"قاعدة البيانات"

العمل المختبري رقم 7

"لغة القواعد بيانات SQL: أوامر معالجة البيانات»

نوفوسيبيرسك 2000

SQL هو اختصار للغة الاستعلام الهيكلية. يتضح من اسم اللغة أن غرضها الرئيسي هو إنشاء استعلامات للحصول على معلومات من قاعدة البيانات. تشكل أوامر استرداد البيانات أساس لغة معالجة البيانات DML - وهي جزء لا يتجزأ من لغة SQL. ومع ذلك، يتكون DML من أكثر من مجرد أوامر لاسترداد البيانات من قاعدة البيانات. هناك أيضًا أوامر لتعديل البيانات وإدارة البيانات وغيرها.

يفحص العمل المخبري الأدوات الأساسية للغة DML. في تَقَدم العمل المختبريسوف نلتزم بمعيار SQL2.

نظرا لحقيقة أن SQL هي لغة كبيرة، فسوف نأخذ في الاعتبار الأوامر الأساسية فقط. يتم تناول العديد من أدوات SQL المحددة في المختبرات اللاحقة.

لأداء العمل المختبري، يلزم معرفة أساسيات نموذج البيانات العلائقية، وأساسيات الجبر العلائقي وحساب التفاضل والتكامل، ومبادئ العمل مع MS SQL Server DBMS.

نتيجة لاستكمال العمل المختبري، سوف تتقن أساليب معالجة البيانات باستخدام أوامر لغة SQL، وتأخذ في الاعتبار لهجة اللغة المطبقة في MS SQL Server DBMS.

مقدمة

يحتوي SQL على مجموعة واسعة من إمكانيات معالجة البيانات، سواء لإنشاء الاستعلامات أو تحديث قاعدة البيانات. تعتمد هذه القدرات فقط على البنية المنطقية لقاعدة البيانات، وليس على بنيتها المادية، والتي تتوافق مع متطلبات النموذج العلائقي.

كان الهيكل الأصلي لبناء جملة SQL (أو على الأقل يبدو أنه) يعتمد على حساب التفاضل والتكامل العلائقي لـ Codd. العملية الوحيدة المدعومة في الجبر العلائقي كانت الاتحاد.

بالإضافة إلى بناء الجملة الشبيه بحساب التفاضل والتكامل الذي تم تطويره في المعيار السابق، ينفذ SQL2 مباشرة عمليات الاتحاد والتقاطع والفرق والانضمام. كانت عمليات التحديد والمشروع والمنتج (ولا تزال) مدعومة بشكل مباشر تقريبًا، في حين يتم دعم عمليات التقسيم والتخصيص بشكل أكثر تعقيدًا.

سنقوم أولاً بوصف لغة الاستعلام SQL ومن ثم عمليات إدخال البيانات وتعديلها. سيتم وصف عمليات تعديل البيانات أخيرًا، نظرًا لأن بنيتها تعتمد إلى حد ما على بنية لغة الاستعلام.

استفسارات بسيطة

لنا طلب بسيطسيكون هناك استعلام يصل إلى جدول واحد فقط في قاعدة البيانات. ستساعدنا الاستعلامات البسيطة في توضيح البنية الأساسية لـ SQL.

طلب بسيط.استعلام يصل إلى جدول قاعدة بيانات واحد فقط.

طلب:من يعمل كجص؟

حيث SKILL_TYPE = "الجص"

نتيجة:

جي ريكوفر

يوضح هذا الاستعلام الثلاثة الأكثر شيوعًا عبارات SQL: حدد ومن وأين. على الرغم من أننا وضعناها في مثالنا على خطوط مختلفة، إلا أنها يمكن أن تظهر جميعها على نفس السطر. يمكن أيضًا وضع مسافة بادئة لها بشكل مختلف، ويمكن فصل الكلمات داخل العبارات بعدد عشوائي من المسافات. دعونا نلقي نظرة على خصائص كل عبارة.

يختار. تسرد جملة SELECT الأعمدة التي يجب أن تظهر في الجدول الناتج. هذه دائمًا أعمدة لبعض الجداول العلائقية. في مثالنا، يتكون الجدول الناتج من عمود واحد (NAME)، ولكن بشكل عام يمكن أن يحتوي على عدة أعمدة؛ ويمكن أن تحتوي أيضًا على قيم أو ثوابت محسوبة. وسنقدم أمثلة على كل خيار من هذه الخيارات. إذا كان الجدول الناتج يجب أن يحتوي على أكثر من عمود واحد، فسيتم إدراج كافة الأعمدة المطلوبة بعد ذلك حدد الأوامرمفصولة بفواصل. على سبيل المثال، ستؤدي العبارة SELECT WORKER_ID, NAME إلى إنشاء جدول يتكون من العمودين WORKER_ID وNAME.

جملة التحديد.يحدد أعمدة الجدول الناتج.

من. تحدد جملة FROM واحدًا أو أكثر من الجداول التي يمكن الوصول إليها عن طريق الاستعلام. يجب أن تكون كافة الأعمدة المدرجة في جملتي SELECT وWHERE موجودة في أحد الجداول المدرجة في الأمر FROM. في SQL2، يمكن تعريف هذه الجداول مباشرة في المخطط كجداول أساسية أو طرق عرض بيانات، أو يمكن أن تكون هي نفسها جداول غير مسماة ناتجة عن استعلامات SQL. في الحالة الأخيرة، يتم تقديم الطلب بشكل صريح في الأمر FROM.

عبارة "من".تحديد الجداول الموجودة التي يتم الوصول إليها عن طريق الاستعلام.

أين. جملة WHERE تحتوي على شرط. وعلى أساسه يتم اختيار صفوف الجدول (الجداول). في مثالنا، الشرط هو أن العمود SKILL_TYPE يجب أن يحتوي على الثابت "Plasterer" المحاط بفواصل عليا، كما هو الحال دائمًا مع الثوابت النصية في SQL. جملة WHERE هي أمر SQL الأكثر تقلبًا؛ قد تحتوي على العديد من الشروط المختلفة. سيتم تخصيص جزء كبير من مناقشتنا لتوضيح التركيبات المختلفة المسموح بها في أمر WHERE.

حيث الشرطية.يحدد الشرط بناءً على تحديد الصفوف من الجداول المحددة.

تتم معالجة استعلام SQL أعلاه بواسطة النظام بالترتيب التالي: من، أين، حدد. أي أن صفوف الجدول المحددة في الأمر FROM يتم وضعها في منطقة العمل للمعالجة. يتم بعد ذلك تطبيق جملة WHERE على كل صف بالتسلسل. يتم استبعاد كافة الصفوف التي لا تستوفي شرط WHERE من الاعتبار. ثم تتم معالجة تلك الصفوف التي تستوفي شرط WHERE بواسطة عبارة SELECT. في مثالنا، يتم تحديد NAME من كل صف من هذا القبيل، ويتم إخراج جميع القيم المحددة كنتائج استعلام.

طلب:توفير كافة المعلومات حول مباني المكاتب.

أين النوع = "المكتب"

نتيجة:

نوع عنوان معرف المبنى، حالة المستوى QLTY

312 ش العلم 123 مكتب 2 2

210 شارع بيريزوفايا. 1011 مكتب ز 1

111 شارع أوسينوفايا. 1213 مكتب 4 1

العلامة النجمية (*) في أمر SELECT تعني "الصف بأكمله". هذا اختصار مناسب سنستخدمه كثيرًا.

طلب:ما هو الراتب الأسبوعي لكل كهربائي؟

اختر الاسم، "الراتب الأسبوعي = "، 40 * HRLY_RATE

حيث SKILL_TYPE = "كهربائي"

نتيجة:

م. فاراداي الراتب الأسبوعي = 500.00

راتب إتش كولومبوس الأسبوعي = 620.00

يوضح هذا الاستعلام استخدام ثوابت الأحرف (في مثالنا "الراتب الأسبوعي =") والعمليات الحسابية في أمر SELECT. ضمن عبارة SELECT، يمكنك إجراء عمليات حسابية تستخدم أعمدة رقمية وثوابت رقمية، بالإضافة إلى عوامل التشغيل الحسابية القياسية ( +، -، *، /)، مجمعة حسب الضرورة باستخدام الأقواس. لقد قمنا أيضًا بإدراج جديد أمر الطلب BY، الذي يقوم بفرز نتيجة الاستعلام بترتيب أبجدي رقمي تصاعدي حسب العمود المحدد. إذا كنت تريد فرز النتائج بترتيب تنازلي، فستحتاج إلى إضافة DESC إلى الأمر. يمكن لجملة ORDER BY فرز النتائج حسب أعمدة متعددة، بعضها بترتيب تصاعدي والبعض الآخر بترتيب تنازلي. يتم إدراج عمود المفتاح الأساسي للفرز أولاً.

ثابت الحرف.ثابت يتكون من حروف وأرقام وأحرف "خاصة".

طلب:من لديه سعر بالساعة يتراوح بين 10 إلى 12 دولارًا؟

حيث HRLY_RATE > = 10 وHRLY_RATE< - 12

نتيجة:

معرف العاملالاسم HRLY_RATE SKILL_TYPE SUPV_ID

يوضح هذا الاستعلام بعض الميزات الإضافية لعبارة WHERE: عوامل المقارنة وعامل التشغيل المنطقي AND. ستة عوامل مقارنة (=،<>(غير متساوي)،<, >, <=, >=). يمكن استخدام العوامل المنطقية AND وOR وNOT لإنشاء شروط مركبة أو لإبطال شرط ما. يمكن استخدام الأقواس لتجميع الشروط، كما هو شائع في لغات البرمجة.

عوامل المقارنة =،<>, <, >, <=, >=.

العمليات المنطقيةو (و)، أو (أو)، وليس (هو) .

يمكنك أيضًا استخدام عامل التشغيل BETWEEN (بين) لصياغة هذا الاستعلام:

حيث HRLY_RATE بين 10 و12

يمكن استخدام BETWEEN لمقارنة كمية مع كميتين أخريين، الأولى منهما أقل من الثانية، إذا كان من الممكن أن تكون الكمية المقارنة مساوية لكل من هذه الكميات أو أي قيمة بينهما.

الطلب: قائمة الجبس، الأسقف والكهربائيين.

مكان وجود المهارة ("عامل الجص"، "سقف"، "فني الكهرباء")

نتيجة:

اسم معرف_العامل HRLY_RATE SKILL_TYPE SUPV_ID

1412 ك. نيمو 13.75 جص 1520

2920 ر. جاريت 10.00 بناء السقف 2920

1520 ج. ريكوفر 11.75 الجص 1520

يشرح هذا الاستعلام استخدام عامل المقارنة IN (B). يعتبر شرط WHERE صحيحًا إذا كان نوع تخصص الصف موجودًا داخل المجموعة المحددة بين قوسين، أي إذا كان نوع التخصص هو الجبس أو السقف أو الكهربائي. سنرى عامل التشغيل IN مرة أخرى في الاستعلامات الفرعية.

لنفترض أننا لا نستطيع أن نتذكر بالضبط تهجئة تخصصنا: "كهربائي" أو "مهندس إلكترونيات" أو أي شيء آخر. تعمل أحرف البدل، التي تحل محل سلاسل الأحرف غير المحددة، على تسهيل العثور على التهجئة غير الدقيقة في الاستعلام.

رموز الأنماط.الأحرف التي تحل محل سلاسل الأحرف غير المحددة.

طلب:قم بإدراج الموظفين الذين يبدأ نوع تخصصهم بـ "إلك".

أين SKILL_TYPE مثل ("Elect%")

نتيجة:

اسم معرف العامل HRLY_RATE SKILL_TYPE SUPV_ID

1235 م. فاراداي 12.50 كهربائي 1311

1311 هـ. كولومبوس 15.50 إلكتريك 1311

يحتوي SQL على حرفي بدل: % (النسبة المئوية) و_ (شرطة سفلية). تحل الشرطة السفلية محل حرف واحد غير محدد بالضبط. تحل النسبة المئوية محل عدد عشوائي من الأحرف، بدءًا من الصفر. عند استخدام أحرف البدل، يلزم وجود عامل تشغيل LIKE لمقارنة متغيرات الأحرف بالثوابت. أمثلة أخرى:

اسم مثل "__ كولومبوس"

اسم مثل "__K%"

يكون الشرط في المثال الأول صحيحًا إذا كان NAME يتكون من حرفين متبوعًا بـ "Columbus". في جدول "العامل"، تبدأ كافة الأسماء بحرف أولي ونقطة. وبالتالي، باستخدام هذا الشرط نحن. دعونا نجد جميع الموظفين الذين يحملون الاسم الأخير "كولومبوس". شرط المثال الثاني يسمح لنا بالعثور على جميع الموظفين الذين تبدأ أسماؤهم الأخيرة بالحرف "K".

طلب:ابحث عن جميع الوظائف التي تبدأ خلال الأسبوعين المقبلين.

حيث يبدأ التاريخ بين CURRENT_DATE و

نتيجة:(افترض أن التاريخ الحالي هو التاريخ الحالي = 10.10)

WORKER_ID BLDG_ID START_DATE NUM_DAYS

1235 312 10.10 5

1235 515 17.10 22

3231 111 10.10 8

1412 435 15.10 15

3231 312 24.10 20

1311 460 23.10 24

يوضح هذا الاستعلام استخدام عامل التشغيل BETWEEN مع قيم التاريخ والفاصل الزمني. CURRENT_DATE هي دالة تُرجع دائمًا تاريخ اليوم. تعبير

CURRENT_DATE + الفاصل الزمني "14" يومًا

يضيف فترة أسبوعين إلى التاريخ الحالي. ومن ثم، يتم تحديد ASSIGNMENT (بافتراض أن اليوم هو 10/10) إذا كانت قيمة العمود START_DATE تقع بين 10/10 و24/10. من هذا يمكننا أن نرى أنه يمكننا إضافة قيم الفاصل الزمني إلى حقول التاريخ. علاوة على ذلك، يمكننا ضرب قيم الفترات بقيم صحيحة. على سبيل المثال، لنفترض أننا نريد معرفة العدد الذي سيكون في عدد معين من الأسابيع (يُشار إليه بالمتغير NUM_WEEKS). يمكننا أن نفعل ذلك مثل هذا:

CURRENT_DATE + الفاصل الزمني "7" أيام * NUM_WEEKS

2. استعلامات الجداول المتعددة

تعد القدرة على ربط عناصر البيانات عبر حدود جدول واحد أمرًا مهمًا لأي لغة قاعدة بيانات. في الجبر العلائقي، يتم تنفيذ هذه الوظيفة عن طريق عملية الانضمام. على الرغم من أن معظم SQL يعتمد مباشرة على حساب التفاضل والتكامل العلائقي، إلا أن SQL يربط البيانات من جداول مختلفة بطريقة مشابهة لعملية الربط في الجبر العلائقي. الآن سوف نبين كيف يتم ذلك. النظر في الطلب:

طلب:

البيانات المطلوبة للإجابة موجودة في جدولين: العامل والمهمة. يتطلب حل SQL إدراج كلا الجدولين في الأمر FROM وتحديد نوع خاص من جملة WHERE:

حدد SKILL_TYPE

من العامل، المهمة

حيث WORKER.WORKER_ID = ASSIGNMENT.WORKER_ID

و BLDG_ID = 435

ما الذي يحدث هنا؟ يجب أن نأخذ بعين الاعتبار مرحلتين في كيفية معالجة النظام لهذا الطلب.

1. كالعادة، تتم معالجة جملة FROM أولاً. ومع ذلك، في هذه الحالة، نظرًا لأن الأمر يحدد جدولين، يقوم النظام بإنشاء منتج ديكارتي لصفوف هذه الجداول. وهذا يعني أنه يتم إنشاء جدول واحد كبير (منطقيًا) يتكون من أعمدة من كلا الجدولين، بحيث يقترن كل صف من جدول واحد بكل صف من الجدول الآخر. في مثالنا، نظرًا لأن جدول WORKER يحتوي على خمسة أعمدة وجدول ASSIGNMENT يحتوي على أربعة أعمدة، فإن المنتج الديكارتي الذي يتم إنتاجه بواسطة الأمر FROM سيحتوي على تسعة أعمدة. إجمالي عدد صفوف المنتج الديكارتي يساوي m * n، حيث m هو عدد صفوف جدول العامل؛ وn هو عدد الصفوف في جدول التعيين. بما أن جدول العامل يحتوي على 7 صفوف وجدول التعيين يحتوي على 19 صفًا، فإن المنتج الديكارتي سيحتوي على 7x19 أو 133 صفًا. إذا كان الأمر FROM يسرد أكثر من جدولين، فسيتم إنشاء منتج ديكارتي لجميع الجداول المحددة في الأمر.

المنتج الديكارتي. نتيجة ضم كل صف من جدول واحد مع كلصف من جدول آخر.

2. بعد إنشاء الجدول العلائقي العملاق، يستخدم النظام أمر WHERE كما كان من قبل. كل صف من الجدول تم إنشاؤه بواسطة الأمر FROM. يتم التحقق لمعرفة ما إذا كان شرط WHERE قد تم استيفاءه. يتم استبعاد الصفوف التي لا تستوفي الشرط من الاعتبار. ثم يتم تطبيق جملة SELECT على الصفوف المتبقية.

تحتوي جملة WHERE في استعلامنا على شرطين:

1. العامل. WORKER_ID = ASSIGNMENT.WORKER_ID

2.معرف المبنى = 435

أول هذه الشروط هو شرط الانضمام. لاحظ أنه بما أن جدولي WORKER وASSIGNMENT يحتويان على عمود باسم WORKER_ID، فإن منتجهما الديكارتي سيحتوي على عمودين بهذا الاسم. وللتمييز بينهما، نسبق اسم العمود باسم الجدول المصدر، مفصولاً بنقطة.

الشرط الأول يعني أنه في أي صف محدد، يجب أن تتطابق قيمة عمود WORKER_ID من جدول WORKER مع قيمة عمود WORKER_ID من جدول ASSIGNMENT. في الواقع، نحن نربط جدولين بواسطة WORKER_ID. يتم استبعاد جميع الصفوف التي لا تتساوى فيها قيم هذين العمودين من جدول المنتج. بالضبط نفس الشيء يحدث عند إجراء عملية الربط الطبيعية للجبر العلائقي. (ومع ذلك، لا يزال هناك بعض الاختلاف عن الصلة الطبيعية: لا يقوم SQL بإزالة عمود WORKER_ID الإضافي تلقائيًا). يظهر في الشكل الرابط الكامل لهذين الجدولين مع الشرط الإضافي BLDG_ID = 435. 1. سيؤدي استخدام الأمر SELECT في النهاية إلى نتيجة الاستعلام التالية:

نوع المهارة

الجص

سقف

عامل الكهرباء

أرز. 1. الانضمام إلى جدولي العامل والتعيين

سنعرض الآن كيفية ضم جدول إلى نفسه في SQL.

طلب:قائمة الموظفين مع ذكر أسماء مديريهم.

حدد A.WORKER_NAME، B.WORKER_NAME

من العامل أ، العامل ب

حيث B.WORKER_ID = A.SUPV_ID

تقوم جملة FROM في هذا المثال بإنشاء "نسختين" من جدول WORKER، مما يمنحهما الأسماء المستعارة A وB. الاسم المستعار هو اسم بديل يُعطى للجدول. بعد ذلك، يتم ربط النسختين A وB من جدول WORKER بواسطة أمر WHERE استنادًا إلى شرط المساواة لـ WORKER_ID في B وSUPV_ID في A. وبالتالي، يتم ربط كل صف من A بالصف B، الذي يحتوي على معلومات حول مدير الصف A (الصورة 2).

أرز. 2. ضم نسختين من جدول العمال

وباختيار اسمين للموظفين من كل سطر نحصل على القائمة المطلوبة:

A.NAMEB.NAME

إم فاراداي إتش كولومبوس

كيه نيمو جي ريكوفر آر جاريت آر جاريت

بي. ماسون بي. ماسون جي. ريكوفر جي. ريكوفر إتش. كولومبوس إتش. كولومبوس جي. المحامي بي. ماسون

كنية.اسم بديل معين للجدول.

يمثل A.WORKER_NAME العامل ويمثل B.WORKER_NAME المدير. يرجى ملاحظة أن بعض العمال هم مديريهم، وهو ما ينبع من المساواة WORKER_ID - SUPV_ID في سطورهم.

في SQL، يمكنك ربط أكثر من جدولين في وقت واحد:

طلب

حدد العامل_NAME

من العامل والمهمة والبناء

حيث WORKER.WORKER_ID = ASSIGNMENT.WORKER_ID وASSIGNMENT.BLDG_ID = BUILDING.BLDG_ID و

النوع = "المكتب"

نتيجة:

م. فاراداي

جي ريكوفر

J. المحامي

لاحظ أنه في حالة ظهور اسم عمود (على سبيل المثال، WORKER_ID أو BLDG_ID) في أكثر من جدول واحد، لتجنب الغموض، يجب علينا إضافة اسم العمود إلى اسم الجدول الأصلي في المقدمة. ولكن إذا كان اسم العمود موجودًا في جدول واحد فقط، مثل TYPE في مثالنا، فلا يوجد أي غموض، لذلك لا يلزم تحديد اسم الجدول.

تقوم أوامر SQL في هذا الاستعلام بإنشاء جدول واحد من ثلاثة جداول قاعدة بيانات علائقية. يتم ربط الجدولين الأولين بواسطة WORKER_ID، وبعد ذلك يتم ربط الجدول الثالث بواسطة BLDG_ID إلى الجدول الناتج. حالة

النوع = "المكتب"

تؤدي جملة WHERE إلى استبعاد كافة الصفوف باستثناء تلك الخاصة بمباني المكاتب. وهذا يلبي متطلبات الطلب.

3. الاستعلامات الفرعية

استعلام فرعي.الاستعلام داخل الاستعلام

يمكن وضع استعلام فرعي ضمن جملة WHERE للاستعلام، وبالتالي توسيع إمكانيات جملة WHERE. لنلقي نظرة على مثال.

طلب:ما هي تخصصات العاملين في مبنى 435؟

حدد SKTLL_TYPE

من العامل الذي يوجد به معرف_العامل

(حدد WORKER_ID

أين BLDG_ID = 435)

استعلام فرعي في هذا المثال

(حدد WORKER_ID

أين BLDG_ID = 435)

يتم استدعاء الاستعلام الذي يحتوي على استعلام فرعي طلب خارجيأو الطلب الرئيسي. يؤدي الاستعلام الفرعي إلى إنشاء المجموعة التالية من معرفات الموظفين:

معرف العامل

طلب خارجي.الاستعلام الرئيسي الذي يحتوي على كافة الاستعلامات الفرعية.

تحل مجموعة المعرفات هذه محل استعلام فرعي في الاستعلام الخارجي. من الآن فصاعدا، يتم تنفيذ الاستعلام الخارجي باستخدام المجموعة التي أنشأها الاستعلام الفرعي. يعالج الاستعلام الخارجي كل صف من جدول WORKER وفقًا لجملة WHERE. إذا كان WORKER_ID للصف يقع في مجموعة (IN) التي تم إنشاؤها بواسطة الاستعلام الفرعي، فسيتم تحديد SKILL_TYPE للصف وعرضه في الجدول الناتج:

نوع المهارة

الجص

سقف

عامل الكهرباء

من المهم جدًا أن تحتوي جملة SELECT الخاصة بالاستعلام الفرعي على WORKER_ID وWORKER_ID فقط. وإلا، فإن عبارة WHERE الخاصة بالاستعلام الخارجي، والتي تعني أن WORKER_ID موجود في مجموعة معرفات العامل، لن يكون لها أي معنى.

لاحظ أنه يمكن تنفيذ الاستعلام الفرعي بشكل منطقي قبل أن يتم النظر في صف واحد على الأقل بواسطة الاستعلام الرئيسي. بمعنى ما، الاستعلام الفرعي مستقل عن الاستعلام الرئيسي. يمكن تنفيذه كاستعلام كامل. نقول أن مثل هذا الاستعلام الفرعي لا يرتبط بالاستعلام الرئيسي. وكما سنرى قريبًا، يمكن ربط الاستعلامات الفرعية.

استعلام فرعي غير مرتبط.استعلام فرعي تكون قيمته مستقلة عن أي استعلام خارجي.

فيما يلي مثال لاستعلام فرعي داخل استعلام فرعي.

طلب: قائمة الموظفين المعينين في مباني المكاتب.

مرة أخرى ننظر إلى الاستعلام الذي قمنا بفحص الاتصال به.

حدد العامل_MAME

مكان وجود معرف_العامل

(حدد WORKER_ID

مكان BLDG_ID

حيث النوع = "المكتب"))

نتيجة:

م. فاراداي

جي ريكوفر

J. المحامي

لاحظ أننا لا نحتاج إلى بادئة أسماء الأعمدة بأسماء الجداول في أي مكان، نظرًا لأن كل استعلام فرعي يعالج جدولًا واحدًا فقط، لذلك لا يمكن أن ينشأ أي غموض.

يتم تنفيذ الاستعلام بترتيب من الداخل إلى الخارج. أي أنه يتم تنفيذ الاستعلام الأعمق (أو "الأسفل") أولاً، ثم يتم تنفيذ الاستعلام الفرعي الذي يحتوي عليه، ثم الاستعلام الخارجي.

الاستعلامات الفرعية المرتبطة. كانت كافة الاستعلامات الفرعية التي تمت مناقشتها أعلاه مستقلة عن الاستعلامات الرئيسية التي تم استخدامها فيها. نعني بالمستقل أنه يمكن تنفيذ الاستعلامات الفرعية بمفردها كاستعلامات كاملة. ننتقل الآن إلى النظر في فئة من الاستعلامات الفرعية التي يمكن أن تعتمد نتائج تنفيذها على الصف الذي يعتبره الاستعلام الرئيسي. تسمى هذه الاستعلامات الفرعية بالاستعلامات الفرعية المرتبطة.

الاستعلام الفرعي المرتبط. استعلام فرعي تعتمد نتيجته على الصف الذي يتناوله الاستعلام الرئيسي.

طلب:قم بإدراج الموظفين الذين تكون أجورهم بالساعة أعلى من أجور مديريهم.

حدد العامل_NAME

حيث A.HRLY_RATE>

(حدد B.HRLY_RATE

حيث B.WORKER_ID = A.SUPV_ID)

نتيجة:

الخطوات المنطقية لتنفيذ هذا الطلب هي:

1. يقوم النظام بإنشاء نسختين من جدول العمال: النسخة أ والنسخة ب. وفقًا للطريقة التي عرفناها بها، تشير A إلى الموظف، وتشير B إلى المدير.

2. يقوم النظام بعد ذلك بدراسة كل صف A. ويتم تحديد صف معين إذا كان يفي بشرط WHERE. يعني هذا الشرط أنه سيتم تحديد صف إذا كانت قيمته HRLY_RATE أكبر من HRLY_RATE التي تم إنشاؤها بواسطة الاستعلام الفرعي.

3. يحدد الاستعلام الفرعي قيمة HRLY_RATE من الصف B، الذي يساوي WORKER_ID الخاص به SUPV_ID للصف A، في هذه اللحظةيعتبر من خلال الطلب الرئيسي. هذا هو HRLY_RATE للمدير.

لاحظ أنه بما أنه لا يمكن مقارنة A.HRLY_RATE إلا بقيمة واحدة، فيجب أن يُرجع الاستعلام الفرعي قيمة واحدة فقط. تتغير هذه القيمة اعتمادًا على الصف A الذي يتم النظر فيه. وبالتالي، يرتبط الاستعلام الفرعي بالاستعلام الرئيسي. سنرى المزيد من الأمثلة على الاستعلامات الفرعية المرتبطة لاحقًا عندما ندرس الوظائف المضمنة.

موجود وغير موجود عوامل التشغيل

لنفترض أننا نريد تحديد العمال الذين لم يتم تكليفهم بالعمل في مبنى معين. ظاهريًا، يبدو أن مثل هذا الطلب يمكن تلبيته بسهولة بمجرد إلغاء النسخة الإيجابية للطلب. لنفترض، على سبيل المثال، أننا مهتمون بمبنى يحمل BLDG_ID 435. فكر في الطلب:

حدد معرف_العامل

حيث BLDG_ID ليس 435

لسوء الحظ، هذه صياغة غير صحيحة للحل. سيعطينا الطلب ببساطة هويات العمال العاملين في المباني الأخرى. من الواضح أنه يمكن أيضًا تخصيص بعضهم للمبنى 435.

يستخدم الحل الذي تمت صياغته بشكل صحيح عامل التشغيل NOT EXISTS:

حدد معرف_العامل

حيث لا يوجد

حيث ASSIGNMENT.WORKER_ID = WORKER.WORKER_ID و

نتيجة:

معرف_العامل

يتم دائمًا وضع عوامل التشغيل EXISTS وNOT EXISTS قبل الاستعلام الفرعي. يتم تقييم EXISTS إلى true إذا كانت المجموعة التي تم إنشاؤها بواسطة الاستعلام الفرعي ليست فارغة. إذا كانت المجموعة التي تم إنشاؤها بواسطة الاستعلام الفرعي فارغة، فإن EXISTS تأخذ القيمة "خطأ". وبطبيعة الحال، يعمل عامل التشغيل NOT EXISTS بالعكس تمامًا. يكون صحيحًا إذا كانت نتيجة الاستعلام الفرعي فارغة، ويكون غير صحيح.

يوجد عامل تشغيل. يُرجع صحيحًا إذا لم تكن مجموعة النتائج فارغة.

غير موجود المشغل. يُرجع صحيحًا إذا كانت مجموعة النتائج فارغة.

في هذا المثال استخدمنا عامل التشغيل NOT EXISTS. يحدد الاستعلام الفرعي جميع صفوف جدول ASSIGNMENT الذي يكون فيه WORKER_ID له نفس قيمة الصف الذي يعتبره الاستعلام الرئيسي، وBLDG_ID يساوي 435. إذا كانت هذه المجموعة فارغة، فإن صف العامل الذي يعتبره الاستعلام الرئيسي هو تم تحديده، لأن هذا يعني أن هذا الموظف لا يعمل في المبنى 435.

في الحل الذي قدمناه، استخدمنا استعلامًا فرعيًا مرتبطًا. إذا استخدمنا عامل التشغيل IN بدلاً من NOT EXISTS، فيمكننا التعامل مع استعلام فرعي غير مرتبط:

حدد معرف_العامل

حيث لا يوجد معرّف العامل

(حدد WORKER_ID

حيث BLDG_ID = 435)

هذا الحل أبسط من الحل مع عامل التشغيل NOT EXISTS. يطرح سؤال طبيعي: لماذا نحتاج إلى موجود وغير موجود على الإطلاق؟ الجواب هو أن NOT EXISTS هي الطريقة الوحيدة لحل الاستعلامات التي تحتوي على كلمة "every" في الشرط. يتم حل مثل هذه الاستفسارات في الجبر العلائقي باستخدام عملية القسمة، وفي حساب التفاضل والتكامل العلائقي باستخدام المحدد الكمي العالمي. فيما يلي مثال لاستعلام يحتوي على كلمة "كل" في حالته:

طلب:قائمة الموظفين المعينين لكل مبنى.

يمكن تنفيذ هذا السؤال في SQL باستخدام النفي المزدوج. سنقوم بإعادة صياغة الاستعلام ليشمل علامة سلبية مزدوجة:

طلب:قائمة هؤلاء الموظفين لمن لاهناك مبنى لم يتم تخصيصهم له.

لقد أبرزنا السلبية المزدوجة. ومن الواضح أن هذا الطلب يعادل منطقيا الطلب السابق.

الآن نريد صياغة الحل في SQL. ولتسهيل فهم الحل النهائي، نعطي أولا حلا لمشكلة أولية وهي مشكلة تحديد جميع المباني التي يعمل لها عامل افتراضي "1234" لامعين.

(ط) حدد BLDG_ID

حيث لا يوجد

ASSIGNMENT.WORKER_ID = 1234)

لقد وضعنا علامة (I) على هذا الاستعلام لأننا سنشير إليه لاحقًا. إذا لم يكن هناك مبنى يلبي هذا الطلب، فسيتم تعيين العامل 1234 لكل مبنى وبالتالي يستوفي شروط الطلب الأصلي. لكي نحصل على حل للاستعلام الأصلي يجب علينا تعميم الاستعلام (I) من عامل محدد 1234 إلى المتغير WORKER_ID وتحويل هذا الاستعلام المعدل إلى استعلام فرعي للاستعلام الأكبر. وهنا الحل:

(ثانيًا) حدد WORKER_ID

حيث لا يوجد

حيث لا يوجد

حيث ASSIGNMENT.BLDG_ID = BUILDING.BLDG_ID و

ASSIGNMENT.WORKER_ID = WORKER.WORKER_ID)

نتيجة:

معرف العامل

لاحظ أن الاستعلام الفرعي الذي يبدأ في السطر الرابع من الاستعلام (II) مطابق للاستعلام (I)، مع استبدال "1234" بـ WORKER.WORKER_ID. يمكن قراءة الاستعلام (II) على النحو التالي:

حدد WORKER_ID من WORKER إذا لم يكن هناك مبنى لم يتم تعيين WORKER_ID له.

وهذا يتوافق مع شروط الطلب الأصلي.

نرى أنه يمكن استخدام العامل NOT EXISTS لصياغة تلك الاستعلامات التي تتطلب عملية قسمة في الجبر العلائقي، ومحددًا كميًا عالميًا في حساب التفاضل والتكامل العلائقي. من وجهة نظر سهولة الاستخدام، لا يقدم عامل التشغيل NOT EXISTS أي فائدة خاصة، مما يعني أن استعلامات SQL التي تستخدم NOT EXISTS مرتين ليست أسهل في الفهم من حلول الجبر العلائقي مع حلول القسمة أو حساب التفاضل والتكامل العلائقية مع محددات الكمية العالمية. ستكون هناك حاجة إلى مزيد من البحث لإنشاء بنيات لغوية تسمح بحل مثل هذه الاستعلامات بشكل طبيعي أكثر.

وظائف مدمجة

دعونا نفكر في أسئلة من هذا النوع:

ما هو الحد الأقصى والحد الأدنى لأسعار الساعة؟ ما هو متوسط ​​عدد أيام عمل الموظفين في المبنى 435؟ ما هو إجمالي عدد الأيام المخصصة لأعمال التجصيص للمبنى 312؟ كم عدد التخصصات المختلفة هناك؟

تتطلب الإجابة على هذه الأسئلة وظائف إحصائية تنظر إلى العديد من الصفوف في الجدول وترجع قيمة واحدة. هناك خمس وظائف من هذا القبيل في SQL، تسمى الوظائف المضمنة أو الوظائف المحددة. هذه الوظائف هي SUM (المجموع)، AVG (المتوسط)، COUNT (الكمية)، MAX (الحد الأقصى) و MIN (الحد الأدنى).

وظيفة مدمجة (وظيفة محددة). دالة إحصائية تعمل على صفوف متعددة: SUM (المجموع)، AVG (المتوسط)، COUNT (الكمية)، MAX (الحد الأقصى)، MIN (الحد الأدنى).

طلب:ما هو الحد الأقصى والحد الأدنى لأسعار الساعة؟

حدد الحد الأقصى (HRLY_RATE)، الحد الأدنى (HRLY_RATE)

نتيجة: 17.40, 8.20

وظائف ماكسوMIN تعمل على عمود جدول واحد. ويختارون القيمة القصوى أو الدنيا، على التوالي، من هذا العمود. لا تحتوي صياغة الاستعلام لدينا على جملة WHERE. بالنسبة لمعظم الاستعلامات، قد لا يكون هذا هو الحال، كما يوضح المثال التالي.

طلب:ما هو متوسط ​​عدد أيام عمل الموظفين في المبنى 435؟

حدد المتوسط ​​(NUM_DAYS)

حيث BLDG_ID = 435

نتيجة: 12.33

طلب:ما هو إجمالي عدد الأيام المخصصة لأعمال التجصيص للمبنى 312؟

حدد المجموع (NUM_DAYS)

من المهمة أيها العامل

حيث WORKER.WORKER_ID = ASSIGNMENT.WORKER_ID و

SKILL_TYPE = "الجص" و

نتيجة: 27

يستخدم الحل صلة بين الجدولين ASSIGNMENT وWORKER. يعد ذلك ضروريًا لأن SKILL_TYPE موجود في جدول WORKER وBLDG_ID موجود في جدول ASSIGNMENT.

طلب:كم عدد التخصصات المختلفة هناك؟

حدد العدد (نوع المهارة المميزة)

نتيجة: 4

نظرًا لأن نفس التخصص يمكن أن يظهر في عدة صفوف مختلفة، يجب عليك استخدام الكلمة الأساسية DISTINCT في هذا الاستعلام لمنع النظام من حساب نفس نوع التخصص أكثر من مرة. يمكن استخدام عامل التشغيل DISTINCT مع أي من الوظائف المضمنة، على الرغم من أنه بالطبع زائد عن الحاجة مع وظائف MAX وMIN.

متميز. عامل يعمل على إزالة الخطوط المكررة.

يجب استخدام الدالتين SUM وAVG مع الأعمدة الرقمية فقط. يمكن استخدام وظائف أخرى مع كل من البيانات الرقمية والحرفية. يمكن استخدام جميع الدوال باستثناء COUNT مع التعبيرات المحسوبة. على سبيل المثال:

طلب:ما هو متوسط ​​الراتب الأسبوعي؟

حدد المتوسط ​​(40 * HRLY_RATE)

نتيجة: 509.14

يمكن أن يشير COUNT إلى صف كامل بدلاً من عمود فردي :

طلب: كم عدد المباني التي لديها مستوى الجودة 3؟

اختر العدد (*)

من المبنى حيث

نتيجة: 3

كما توضح كل هذه الأمثلة، إذا كان أمر SELECT يحتوي على وظيفة مضمنة، فلا يمكن أن يظهر أي شيء آخر في أمر SELECT هذا. الاستثناء الوحيد لهذه القاعدة هو عبارة GROUP BY، والتي سنلقي نظرة عليها الآن.

GROUP BY وHAVING الجمل

في الإدارة، غالبًا ما تكون المعلومات الإحصائية حول كل مجموعة في العديد من المجموعات مطلوبة. على سبيل المثال، فكر في الاستعلام التالي:

طلب:لكل مدير، اكتشف الحد الأقصى لسعر الساعة بين مرؤوسيه.

ولحل هذه المشكلة يجب علينا تقسيم العمال إلى مجموعات حسب مديريهم. وسنقوم بعد ذلك بتحديد الحد الأقصى لعرض التسعير داخل كل مجموعة. في SQL يتم ذلك بهذه الطريقة:

المجموعة حسب SUPV_ID

نتيجة:

SUPV_IDMAX (سعر الساعة)

عند معالجة هذا الاستعلام، يقوم النظام أولاً بتقسيم صفوف جدول العامل إلى مجموعات باستخدام القاعدة التالية. يتم وضع الصفوف في نفس المجموعة فقط إذا كانت تحتوي على نفس SUPV_ID. ثم يتم تطبيق جملة SELECT على كل مجموعة. نظرًا لوجود قيمة SUPV_ID واحدة فقط في هذه المجموعة، فلا يوجد أي شك في SUPV_ID في المجموعة. بالنسبة لكل مجموعة، تقوم جملة SELECT بإخراج SUPV_ID وتقوم أيضًا بحساب وإخراج القيمة MAX(HRLY_RATE). والنتيجة معروضة أعلاه.

في أمر SELECT الذي يحتوي على وظائف مضمنة، يمكن أن تظهر فقط تلك الأعمدة المضمنة في جملة GROUP BY. لاحظ أنه يمكن استخدام SUPV_ID في أمر SELECT لأنه مضمن في جملة GROUP BY.

جملة GROUP BY. يشير إلى أنه يجب تقسيم الصفوف إلى مجموعات ذات قيم مشتركة للعمود (الأعمدة) المحدد.

تسمح لك جملة GROUP BY بإجراء بعض العمليات الحسابية المعقدة. على سبيل المثال، قد نرغب في معرفة متوسط ​​الحد الأقصى لعروض التسعير هذه. ومع ذلك، فإن الحساب باستخدام الوظائف المضمنة محدود بمعنى أنه لا يسمح باستخدام الوظائف المضمنة داخل وظائف مضمنة أخرى. لذلك تعبير مثل

المتوسط ​​(MAX(HRLY_RATE))

مُحرَّم. سيتألف تنفيذ هذا الطلب من مرحلتين. يجب علينا أولاً وضع الحد الأقصى لعروض الأسعار في جدول جديد، وفي خطوة ثانية، نحسب متوسطها.

يمكنك استخدام جملة WHERE مع أمر GROUP BY:

طلب:اكتشف كل نوع من أنواع المباني مستوى متوسطالجودة بين المباني ذات المكانة 1.

اختر النوع، المتوسط ​​(QLTY_LEVEL)

حيث الحالة = 1

نتيجة:

TYPEAVG(QLTY_LEVEL)

المتجر 1

مبنى سكني 3

يتم تنفيذ جملة WHERE قبل عبارة GROUP BY. وبالتالي، لا يمكن لأي مجموعة أن تحتوي على صف له حالة أخرى غير 1. يتم تجميع صفوف الحالة 1 حسب قيمة TYPE، ثم يتم تطبيق جملة SELECT على كل مجموعة.

وجود عبارة. يضع الشروط على المجموعات.

يمكننا أيضًا تطبيق الشروط على المجموعات التي تم إنشاؤها بواسطة جملة GROUP BY. ويتم ذلك باستخدام عبارة HAVING. لنفترض، على سبيل المثال، أننا قررنا أن نجعل أحد الاستعلامات السابقة أكثر تحديدًا:

طلب: لكل مدير لديه أكثر من مرؤوس، تعرف على الحد الأقصى لسعر الساعة بين مرؤوسيه.

يمكننا أن نعكس هذا الشرط باستخدام أمر HAVING المناسب:

حدد SUPV_ID، الحد الأقصى (HRLY_RATE)

من مجموعة العمل بواسطة SUPV_ID

وجود العد(*) > 1

نتيجة:

SUPV_ID MAX(HRLY_RATE)

الفرق بين جمل WHERE وHAVING هو أن WHERE ينطبق على الصفوف، بينما ينطبق HAVING على المجموعات.

يمكن أن يحتوي الاستعلام على عبارة WHERE وعبارة HAVING. في هذه الحالة، يتم تنفيذ جملة WHERE أولاً لأنها يتم تنفيذها قبل التجميع. على سبيل المثال، خذ بعين الاعتبار التعديل التالي للاستعلام السابق:

طلب: لكل نوع من المباني، اكتشف متوسط ​​مستوى الجودة بين المباني ذات الحالة 1. خذ بعين الاعتبار فقط تلك الأنواع من المباني التي لا يتجاوز مستوى الجودة الأقصى 3.

اختر النوع، المتوسط ​​(QLTY_JLEVEL)

حيث الحالة = 1

الحصول على الحد الأقصى (QLTY_LEVEL)<= 3

نتيجة:

نوع المتوسط ​​(QLTY_LEVEL)

المتجر 1

مبنى سكني 3

لاحظ أنه بدءًا من عبارة FROM، يتم تنفيذ العبارات بالترتيب، ثم يتم تطبيق جملة SELECT. وبالتالي، يتم تطبيق جملة WHERE على جدول BUILDING، ويتم حذف كافة الصفوف التي تختلف فيها الحالة عن 1. يتم تجميع الصفوف المتبقية حسب TYPE؛ تنتهي كافة الصفوف التي لها نفس قيمة TYPE في نفس المجموعة. وبالتالي، يتم إنشاء عدة مجموعات، واحدة لكل قيمة TYPE. يتم بعد ذلك تطبيق جملة HAVING على كل مجموعة، وتتم إزالة المجموعات التي تتجاوز قيمة مستوى الجودة القصوى لها 3. وأخيرا، يتم تطبيق جملة SELECT على المجموعات المتبقية.

7. الوظائف المضمنة والاستعلامات الفرعية

لا يمكن استخدام الوظائف المضمنة إلا في عبارة SELECT أو أمر HAVING. ومع ذلك، يمكن أن تكون جملة SELECT التي تحتوي على دالة مضمنة جزءًا من استعلام فرعي. دعونا نلقي نظرة على مثال لمثل هذا الاستعلام الفرعي:

طلب:من هم العمال الذين يحصلون على أجر أعلى من المتوسط ​​في الساعة؟

حدد العامل_NAME

حيث HRLY_RATE>

(حدد متوسط(HRLY_RATE)

نتيجة:

هـ. كولومبوس

لاحظ أن الاستعلام الفرعي غير مرتبط بالاستعلام الرئيسي. يقوم الاستعلام الفرعي بإرجاع قيمة واحدة بالضبط - متوسط ​​السعر بالساعة. يقوم الاستعلام الرئيسي بتحديد العامل فقط إذا كان معدله أكبر من المتوسط ​​المحسوب.

يمكن للاستعلامات المرتبطة أيضًا استخدام الوظائف المضمنة:

استعلام: أي موظف لديه أجر بالساعة أعلى من متوسط ​​الأجر بالساعة بين مرؤوسي نفس المدير؟

في هذه الحالة، بدلاً من حساب متوسط ​​أجر الساعة لجميع العمال، يجب علينا حساب متوسط ​​الأجر لكل مجموعة من العمال الذين يقدمون تقاريرهم إلى نفس المدير. علاوة على ذلك، يجب إجراء حساباتنا من جديد لكل عامل تم أخذه بعين الاعتبار في الاستعلام الرئيسي:

حدد أ.العامل_NAME

يسمح لك SQL بتداخل الاستعلامات داخل بعضها البعض. عادةً ما يُرجع الاستعلام الفرعي قيمة واحدة، والتي يتم التحقق منها لمعرفة ما إذا كان المسند صحيحًا.

أنواع مصطلحات البحث:
. المقارنة مع نتيجة الاستعلام الفرعي (=، >=)
. التحقق من الانتماء إلى نتائج الاستعلام الفرعي (IN)
. التحقق من الوجود (موجود)
. المقارنة المتعددة (الكمية) (أي، الكل)

ملاحظات حول الاستعلامات المتداخلة:
. يجب أن يحدد الاستعلام الفرعي عمودًا واحدًا فقط (باستثناء الاستعلام الفرعي الذي يحتوي على مسند موجود)، ويجب أن يتطابق نوع بيانات النتيجة مع نوع بيانات القيمة المحددة في المسند.
. في بعض الحالات، يمكنك استخدام الكلمة الأساسية DISTINCT للتأكد من إرجاع قيمة واحدة.
. لا يمكنك تضمين عبارة ORDER BY أو UNION في استعلام فرعي.
. يمكن وضع الاستعلام الفرعي إما على يسار أو على يمين حالة البحث.
. يمكن للاستعلامات الفرعية استخدام وظائف التجميع بدون عبارة GROUP BY، والتي تُرجع تلقائيًا قيمة خاصة لأي عدد من الصفوف، ومسند IN خاص، وتعبيرات قائمة على الأعمدة.
. كلما أمكن، يجب عليك استخدام صلات جدول JOIN بدلاً من الاستعلامات الفرعية.

أمثلة على الاستعلامات المتداخلة:

اختر * من الطلبات حيث SNum=(اختر SNum من SalesPeople حيث SName='Motika')
اختر * من الطلبات التي يوجد بها SNum IN (اختر SNum FROM SalesPeople WHERE City='London')
اختر * من الطلبات حيث SNum=(اختر SNum المميز من الطلبات حيث CNum=2001)
اختر * من الطلبات حيث Amt>(SELECT AVG(Amt) من الطلبات حيث Odate=10/04/1990)
اختر * من العميل حيث CNum=(SELECT SNum+1000 من SalesPeople حيث SName='Serres')

2) الاستعلامات الفرعية ذات الصلة

في SQL، يمكنك إنشاء استعلامات فرعية تشير إلى جدول من استعلام خارجي. في هذه الحالة، يتم تنفيذ الاستعلام الفرعي عدة مرات، مرة واحدة لكل صف جدول من الاستعلام الخارجي. لذلك، من المهم أن يستخدم الاستعلام الفرعي الفهرس. يمكن للاستعلام الفرعي الوصول إلى نفس الجدول مثل الاستعلام الخارجي. إذا قام الاستعلام الخارجي بإرجاع عدد صغير نسبيًا من الصفوف، فسيكون الاستعلام الفرعي المرتبط أسرع من الاستعلام الفرعي غير المرتبط. إذا قام الاستعلام الفرعي بإرجاع عدد صغير من الصفوف، فسيكون الاستعلام المرتبط أبطأ من الاستعلام غير ذي الصلة.

أمثلة للاستعلامات الفرعية ذات الصلة:

SELECT * FROM SalesPeople Main WHERE 1(SELECT AVG(Amt) FROM Orders O2 WHERE O2.CNum=O1.CNum) // إرجاع جميع الطلبات التي تتجاوز قيمتها متوسط ​​قيمة الطلب لعميل معين

3) المسند موجود

الشكل النحوي: موجود ()

يأخذ المسند استعلامًا فرعيًا كوسيطة ويتم تقييمه على أنه صحيح إذا كان الاستعلام الفرعي يحتوي على مخرجات وخطأ بخلاف ذلك. يتم تنفيذ الاستعلام الفرعي مرة واحدة ويمكن أن يحتوي على عدة أعمدة، حيث لم يتم التحقق من قيمها، ولكن يتم تسجيل نتيجة وجود الصفوف ببساطة.

ملاحظات على المسند EXISTS:
. EXISTS عبارة عن مسند يُرجع TRUE أو FALSE ويمكن استخدامه بمفرده أو مع تعبيرات منطقية أخرى.
. لا يمكن لـ EXISTS استخدام وظائف التجميع في الاستعلام الفرعي الخاص بها.
. في الاستعلامات الفرعية المرتبطة، يتم تنفيذ المسند EXISTS لكل صف من الجدول الخارجي.
. يمكنك دمج المسند الموجود مع صلات الجدول.

أمثلة على المسند EXISTS:

SELECT * FROM Customer WHERE EXISTS(SELECT * FROM Customer WHERE City='San Jose') - إرجاع جميع العملاء إذا كان أي منهم يعيش في San Jose.
SELECT DISTINCT SNum FROM Customer First WHERE NOT موجود (SELECT * FROM Customer Send WHERE Send.SNum=First.SNum and Send.CNumFirst.CNum) - إرجاع أعداد البائعين الذين خدموا عميلاً واحدًا فقط.
حدد DISTINCT F.SNum وSName وF.City FROM SalesPeople F والعميل S حيثما يوجد (اختر * من العميل T حيث S.SNum=T.SNum وS.CNumT.CNum وF.SNum=S.SNum) - الإرجاعات أرقام وأسماء ومدن الإقامة لجميع البائعين الذين خدموا عدة عملاء.
اختر * من SalesPeople Frst حيثما يوجد (اختر * من العميل أرسل أين Frst.SNum=Send.SNum و1

4) مسندات المقارنة الكمية

الشكل النحوي: (=|>|=|) أي|الكل ()

تستخدم هذه المسندات استعلامًا فرعيًا كوسيطة، ومع ذلك، مقارنةً بالمسند الموجود، يتم استخدامها جنبًا إلى جنب مع المسندات العلائقية (=،>=). وبهذا المعنى، فهي تشبه المسند IN، ولكنها تستخدم فقط مع الاستعلامات الفرعية. يسمح المعيار باستخدام الكلمة الأساسية SOME بدلاً من ANY، ولكن لا تدعمها جميع أنظمة إدارة قواعد البيانات (DBMS).

ملاحظات على مسندات المقارنة:
. يتم تقييم المسند ALL إلى TRUE إذا كانت كل قيمة محددة أثناء تنفيذ الاستعلام الفرعي تفي بالشرط المحدد في مسند الاستعلام الخارجي. يتم استخدامه في أغلب الأحيان مع عدم المساواة.
. يتم تقييم المسند ANY إلى TRUE إذا كانت قيمة واحدة على الأقل محددة أثناء تنفيذ الاستعلام الفرعي تفي بالشرط المحدد في مسند الاستعلام الخارجي. يتم استخدامه في أغلب الأحيان مع عدم المساواة.
. إذا لم يُرجع الاستعلام الفرعي أي صفوف، فسيأخذ ALL تلقائيًا القيمة TRUE (يعتبر أن شرط المقارنة قد تم استيفاءه)، وبالنسبة لأي فإنه يأخذ القيمة FALSE.
. إذا كانت المقارنة TRUE لعدم وجود صفوف وكان هناك صف واحد أو أكثر بقيمة NULL، فستُرجع الدالة ANY UNKNOWN.
. إذا كانت المقارنة FALSE لعدم وجود صفوف وكان هناك صف واحد أو أكثر بقيمة NULL، فستُرجع الدالة ALL UNKNOWN.

أمثلة على مسند المقارنة الكمية:

اختر * من موظفي المبيعات حيث المدينة = أي (اختر مدينة من العميل)
اختر * من الطلبات التي يوجد بها الكل (اختر التقييم من العميل حيث المدينة = "روما")

5) المسند التفرد

فريد|متميز ()

يتم استخدام المسند للتحقق من التفرد (غياب التكرارات) في بيانات الإخراج الخاصة بالاستعلام الفرعي. علاوة على ذلك، في المسند UNIQUT، تعتبر السلاسل ذات القيم NULL فريدة، وفي المسند DISTINCT، تعتبر قيمتان غير محددتين متساويتين لبعضهما البعض.

6) مطابقة المسند

مباراة ()

يقوم المسند MATCH باختبار ما إذا كانت قيمة سلسلة الاستعلام ستتطابق مع قيمة أي سلسلة ناتجة عن الاستعلام الفرعي. يختلف هذا الاستعلام الفرعي عن المسندات IN AND ANY من حيث أنه يسمح بمعالجة التطابقات "الجزئية" (PARTIAL) التي يمكن أن تحدث بين الصفوف التي تحتوي على بعض القيم الخالية.

7) الاستعلامات في القسم من

في الواقع، من القانوني استخدام استعلام فرعي حيثما يسمح بمرجع الجدول.

حدد CName، Tot_Amt من العميل، (SELECT CNum، SUM(Amt) AS Tot_Amt من مجموعة الطلبات حسب CNum) حيث المدينة = "لندن" وCustomer.CNum=Orders.CNum
// يُرجع الاستعلام الفرعي المبلغ الإجمالي للطلبات التي قدمها كل عميل من لندن.

8) الاستعلامات العودية

مع العودية
Q1 كما تم تحديده ... من ... أين ...
السؤال الثاني كما تم تحديده ... من ... أين ...




قمة