سؤال

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

SELECT 
    `timestamp`, `fromEmail`, `subject`
FROM `incomingEmails` 
GROUP BY LOWER(`fromEmail`) 
ORDER BY `timestamp` DESC

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

على سبيل المثال ، قد يعود:

fromEmail: john@example.com, subject: hello
fromEmail: mark@example.com, subject: welcome

عندما السجلات في قاعدة البيانات هي:

fromEmail: john@example.com, subject: hello
fromEmail: john@example.com, subject: programming question
fromEmail: mark@example.com, subject: welcome

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

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

المحلول

الحل بسيط هو التفاف الاستعلام في subselect مع النظام البيان أولا وتطبيق مجموعة من في وقت لاحق:

SELECT * FROM ( 
    SELECT `timestamp`, `fromEmail`, `subject`
    FROM `incomingEmails` 
    ORDER BY `timestamp` DESC
) AS tmp_table GROUP BY LOWER(`fromEmail`)

هذا هو مماثل باستخدام الانضمام ولكن يبدو أجمل بكثير.

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

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

كما من 5.6.21 وقد لاحظت مشاكل مع الفريق من قبل في الجدول المؤقت العودة ترتيب الفرز.

اعتبارا من 5.7.5 ONLY_FULL_GROUP_BY يتم تمكين افتراضيا ، أيفإنه من المستحيل استخدام غير مجموع الأعمدة.

انظر http://www.cafewebmaster.com/mysql-order-sort-group https://dev.mysql.com/doc/refman/5.6/en/group-by-handling.html https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html

نصائح أخرى

إليك نهج واحد:

SELECT cur.textID, cur.fromEmail, cur.subject, 
     cur.timestamp, cur.read
FROM incomingEmails cur
LEFT JOIN incomingEmails next
    on cur.fromEmail = next.fromEmail
    and cur.timestamp < next.timestamp
WHERE next.timestamp is null
and cur.toUserID = '$userID' 
ORDER BY LOWER(cur.fromEmail)

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

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

LEFT JOIN incomingEmails next
    on cur.fromEmail = next.fromEmail
    and cur.id < next.id

والقيام GROUP BY بعد ORDER BY التفاف الاستعلام الخاص بك مع GROUP BY مثل هذا:

SELECT t.* FROM (SELECT * FROM table ORDER BY time DESC) t GROUP BY t.from

وكما أشار في الرد بالفعل، فإن الجواب الحالية خاطئة، لأن GROUP BY يختار تعسفي سجل من النافذة.

إذا واحد هو استخدام الخلية 5.6، أو الخلية 5.7 مع ONLY_FULL_GROUP_BY، والصحيح (حتمية) الاستعلام:

SELECT incomingEmails.*
  FROM (
    SELECT fromEmail, MAX(timestamp) `timestamp`
    FROM incomingEmails
    GROUP BY fromEmail
  ) filtered_incomingEmails
  JOIN incomingEmails USING (fromEmail, timestamp)
GROUP BY fromEmail, timestamp

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

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

وفقا لمعيار SQL لا يمكنك استخدام الأعمدة غير المجمعة في قائمة التحديد. الخلية يسمح هذا الاستخدام (uless وضع ONLY_FULL_GROUP_BY استخدامها) ولكن نتيجة لا يمكن التنبؤ بها.

ONLY_FULL_GROUP_BY

يجب عليك أولا تحديد fromEmail، MIN (اقرأ)، وبعد ذلك، مع الاستعلام الثاني (أو فرعي) - مع مراعاة

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

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

والمفتاح لفهم هذا هو أن الاستعلام لا يمكن إلا أن المعنى إذا كانت هذه الحقول الأخرى ثابتة لأي كيان الذي يرضي ماكس ()، وذلك من حيث نوع القطع الأخرى من سلسلة يمكن تجاهلها. وهذا ما يفسر كيفية القيام بذلك في أسفل جدا من هذا الرابط. http://dev.mysql.com/doc /refman/5.0/en/group-by-hidden-columns.html

وإذا كان يمكنك الحصول صباحا إدراج / الحدث التحديث (مثل الزناد) إلى ما قبل حساب سلسلة من الحقول التي يمكن أن مؤشر عليها والاستعلام سيكون بأسرع ما إذا كانت مجموعة من أكثر من الحقل الذي يريد فعلا إلى MAX (). يمكنك حتى استخدامها للحصول على الحد الأقصى من حقول متعددة. أنا استخدامها للقيام استعلامات مقابل أشجار متعددة الأبعاد expresssed أنها مجموعات متداخلة.

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