سؤال

أحتاج إلى الاستعلام عن قاعدة البيانات هذه للحصول على كل صف، ولكن أيضًا مجموع إحدى قيم أعمدة النتائج.يمكنني استخدام php للحصول على القيمة الإجمالية، ولكن بعد ذلك سأحتاج إلى تشغيل حلقتين، واحدة للحصول على الإجمالي (الذي يظهر في الأعلى فوق النتائج).لذلك أفضّل أن يلتقطه الاستعلام وأن يقوم فقط بإنشاء صف "إجمالي"، ولكن الطريقة الوحيدة التي جعلته يعمل هي باستخدام استعلام فرعي يعد في الأساس تكرارًا للاستعلام الأصلي.هل هناك طريقة أفضل؟

SELECT 
CONCAT(u.firstname, ' ', u.lastname ) name, u.id, s.description, s.shiftstart, s.shiftend, 
    (SELECT 
    SUM( TIME_TO_SEC( TIMEDIFF( shiftend, shiftstart ) ) ) /3600
    FROM shifts
    WHERE id =  '$user'
    AND DATE( shiftstart )
    BETWEEN '$start'
    AND '$end') total
FROM shifts s
INNER JOIN users u ON ( s.id = u.id )
WHERE s.id = '$user'
AND DATE( shiftstart )
BETWEEN '$start'
AND '$end'
ORDER BY shiftstart

الأعمال والمخرجات المذكورة أعلاه:

name        id     description  shiftstart             shiftend               total
Joe User    joeuser    Stuff    2009-01-05 07:45:00    2009-01-05 12:15:00    39.5000
Joe User    joeuser    Stuff    2009-01-05 13:00:00    2009-01-05 17:00:00    39.5000
Joe User    joeuser    Stuff    2009-01-06 07:45:00    2009-01-06 10:45:00    39.5000
Joe User    joeuser    Stuff    2009-01-06 10:45:00    2009-01-06 12:45:00    39.5000
Joe User    joeuser    Stuff    2009-01-06 13:30:00    2009-01-06 14:30:00    39.5000
Joe User    joeuser    Stuff    2009-01-06 14:30:00    2009-01-06 17:00:00    39.5000
Joe User    joeuser    Stuff    2009-01-07 09:45:00    2009-01-07 14:00:00    39.5000
Joe User    joeuser    Stuff    2009-01-07 15:00:00    2009-01-07 17:00:00    39.5000
Joe User    joeuser    Stuff    2009-01-08 08:00:00    2009-01-08 12:15:00    39.5000
Joe User    joeuser    Stuff    2009-01-08 13:15:00    2009-01-08 17:00:00    39.5000
Joe User    joeuser    Stuff    2009-01-09 07:45:00    2009-01-09 10:45:00    39.5000
Joe User    joeuser    Stuff    2009-01-09 11:45:00    2009-01-09 15:15:00    39.5000
Joe User    joeuser    Stuff    2009-01-09 15:15:00    2009-01-09 17:00:00    39.5000

وهو ما أحتاجه، ولكن ربما ليس أفضل طريقة للحصول عليه.

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

المحلول

والخلية تدعم مجموعة من قبل خاصة معدل دعا ROLLUP .

SELECT CONCAT(u.firstname, ' ', u.lastname ) name, u.id, 
  s.description, s.shiftstart, s.shiftend, 
  SUM( TIME_TO_SEC( TIMEDIFF( shiftend, shiftstart ) ) ) /3600 total
FROM shifts s INNER JOIN users u ON ( s.id = u.id )
WHERE s.id = ? AND DATE( shiftstart ) BETWEEN ? AND ?
GROUP BY u.id, s.shiftstart WITH ROLLUP
ORDER BY shiftstart;

نصائح أخرى

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

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

بعض النصائح الأخرى - مساحة القرص رخيصة ويتم قراءة معظم جداول قاعدة البيانات أكثر بكثير مما تتم كتابته.قم بإعداد مشغل إدراج/تحديث (إن أمكن في MySQL) لملء عمود منفصل بالحقول المحسوبة مثل "CONCAT(u.firstname,' ',u.lastname)"واستخدم ذلك للاستعلامات.الوظائف لكل صف غير قابلة للتطوير وسوف تقتل أداء نظام إدارة قواعد البيانات (DBMS) الخاص بك عندما يكبر.

وأي شيء يمكن أن يكون أفضل من خلال المقارنة. والسؤال هو مقارنة ما، أليس كذلك؟

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

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

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

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

وتحرير: باكس بضربي على زر "حفظ" ... لول ...

استخدم تمديد الخلية قدمت بالضبط لهذا الغرض، كما هو موضح في استجابة بيل Karwin (التي كنت upvoted نفسي).

إذا لم تكن متوفرة هذا الخيار 2 ستكون عبارة SQL آخر: SUM SELECT ...) SQL حقا هو الأمثل لتكون فعالة للغاية لهذا النوع من الشيء، بالمقارنة مع أي رمز الإجرائي حلقات أنت من المحتمل أن الكتابة.

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