لماذا أحتاج إلى تحديد جميع الأعمدة بشكل صريح في جملة SQL "Group by" - لماذا لا "Group by *"؟

StackOverflow https://stackoverflow.com/questions/2777235

سؤال

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

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

هل كانت مفيدة؟

المحلول

من الصعب معرفة بالضبط ما يفكر فيه مصممي لغة SQL عندما كتبوا المعيار ، لكن هذا رأيي.

يتطلب منك SQL ، كقاعدة عامة ، أن توضح توقعاتك بشكل صريح ونيتك. اللغة لا تحاول "خمن ما قصدته", ، وملء الفراغات تلقائيا. هذا أمر جيد.

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

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

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

نصائح أخرى

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

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

فمثلا.

Select column1, SUM(column2) AS sum
 FROM table1
 GROUP BY column1, column3

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

يبدو أنه اختصار بسيط للسيناريو الأكثر شيوعًا بشكل كبير (تجميع كل من الأعمدة غير المجمعة) سيكون أداة بسيطة ولكنها فعالة لتسريع الترميز.

ربما "GROUP BY *"

نظرًا لأنه أمر شائع بالفعل في أدوات SQL للسماح بالإشارات إلى الأعمدة حسب رقم عمود النتيجة (أي. GROUP BY 1,2,3, وما إلى ذلك) يبدو أنه من الأبسط أن يكون قادرًا على السماح للمستخدم بتضمين جميع الحقول غير المجمعة تلقائيًا في ضغط مفتاح واحد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top