สิ่งที่คุณกำลังอ่านจะค่อนข้างแฮ็กดังนั้นอย่าลองทำที่บ้าน!
ใน SQL โดยทั่วไปคำตอบสำหรับคำถามของคุณคือNOแต่เนื่องจากโหมดที่ผ่อนคลายของGROUP BY
(กล่าวถึงโดย@bluefeet ) คำตอบคือYESใน MySQL
สมมติว่าคุณมีดัชนี BTREE ใน (post_status, post_type, post_author, post_date) ดัชนีมีลักษณะอย่างไรภายใต้ประทุน?
(post_status = 'เผยแพร่', post_type = 'โพสต์', post_author = 'ผู้ใช้ A', post_date = '2012-12-01') (post_status = 'เผยแพร่', post_type = 'โพสต์', post_author = 'ผู้ใช้ A', post_date = '2012-12-31') (post_status = 'เผยแพร่', post_type = 'โพสต์', post_author = 'ผู้ใช้ B', post_date = '2012-10-01') (post_status = 'เผยแพร่', post_type = ' โพสต์ ', post_author =' ผู้ใช้ B ', post_date =' 2012-12-01 ')
นั่นคือข้อมูลจะถูกจัดเรียงตามเขตข้อมูลทั้งหมดในลำดับจากน้อยไปหามาก
เมื่อคุณทำGROUP BY
ตามค่าเริ่มต้นมันจะเรียงลำดับข้อมูลตามเขตข้อมูลการจัดกลุ่ม ( post_author
ในกรณีของเราคือ post_status, post_type เป็นข้อกำหนดตามWHERE
ข้อ) และหากมีดัชนีที่ตรงกันจะใช้ข้อมูลสำหรับแต่ละระเบียนแรกในลำดับจากน้อยไปหามาก นั่นคือแบบสอบถามจะดึงข้อมูลต่อไปนี้ (โพสต์แรกสำหรับผู้ใช้แต่ละคน):
(post_status = 'เผยแพร่', post_type = 'โพสต์', post_author = 'ผู้ใช้ A', post_date = '2012-12-01') (post_status = 'เผยแพร่', post_type = 'โพสต์', post_author = 'ผู้ใช้ B', post_date = '2012/10/01')
แต่GROUP BY
ใน MySQL อนุญาตให้คุณระบุคำสั่งอย่างชัดเจน และเมื่อคุณขอpost_user
เรียงจากมากไปน้อยมันก็จะผ่านดัชนีของเราในลำดับตรงกันข้ามยังคงบันทึกแรกสำหรับแต่ละกลุ่มที่เป็นจริงสุดท้าย
นั่นคือ
...
WHERE wp_posts.post_status='publish' AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author DESC
จะให้เรา
(post_status = 'เผยแพร่', post_type = 'โพสต์', post_author = 'ผู้ใช้ B', post_date = '2012-12-01') (post_status = 'เผยแพร่', post_type = 'โพสต์', post_author = 'ผู้ใช้ A', post_date = '2012-12-31')
ตอนนี้เมื่อคุณสั่งซื้อผลลัพธ์ของการจัดกลุ่มโดย post_date คุณจะได้รับข้อมูลที่คุณต้องการ
SELECT wp_posts.*
FROM wp_posts
WHERE wp_posts.post_status='publish' AND wp_posts.post_type='post'
GROUP BY wp_posts.post_author DESC
ORDER BY wp_posts.post_date DESC;
หมายเหตุ :
นี่ไม่ใช่สิ่งที่ฉันอยากจะแนะนำสำหรับคำค้นหานี้โดยเฉพาะ ในกรณีนี้ฉันจะใช้เวอร์ชันที่แก้ไขเล็กน้อยของสิ่งที่@bluefeetแนะนำ แต่เทคนิคนี้อาจมีประโยชน์มาก ลองดูคำตอบของฉันที่นี่: การดึงข้อมูลล่าสุดในแต่ละกลุ่ม
ข้อผิดพลาด : ข้อเสียของวิธีการคือ
- ผลลัพธ์ของแบบสอบถามขึ้นอยู่กับดัชนีซึ่งขัดต่อเจตนารมณ์ของ SQL (ดัชนีควรเพิ่มความเร็วการสืบค้น);
- ดัชนีไม่ทราบอะไรเกี่ยวกับอิทธิพลที่มีต่อคิวรี (คุณหรือคนอื่น ๆ ในอนาคตอาจพบว่าดัชนีใช้ทรัพยากรมากเกินไปและเปลี่ยนแปลงอย่างใดก็ตามทำให้การแบ่งผลลัพธ์คิวรีไม่เพียง แต่ประสิทธิภาพ)
- หากคุณไม่เข้าใจวิธีการทำงานของแบบสอบถามส่วนใหญ่คุณจะลืมคำอธิบายในหนึ่งเดือนและแบบสอบถามจะทำให้คุณและเพื่อนร่วมงานสับสน
ข้อดีคือประสิทธิภาพในกรณียาก ในกรณีนี้ประสิทธิภาพของการสืบค้นควรเหมือนกับในการสืบค้นของ @ bluefeet เนื่องจากจำนวนข้อมูลที่เกี่ยวข้องในการเรียงลำดับ (ข้อมูลทั้งหมดถูกโหลดลงในตารางชั่วคราวแล้วเรียงลำดับแล้ว btw แบบสอบถามของเขาต้องการ(post_status, post_type, post_author, post_date)
ดัชนีเช่นกัน) .
สิ่งที่ฉันอยากจะแนะนำ :
ดังที่ฉันได้กล่าวแบบสอบถามเหล่านั้นทำให้ MySQL เสียเวลาในการเรียงลำดับข้อมูลจำนวนมหาศาลในตารางชั่วคราว ในกรณีที่คุณต้องการเพจ (ที่เกี่ยวข้องกับ LIMIT) ข้อมูลส่วนใหญ่จะถูกโยนทิ้ง สิ่งที่ฉันจะทำคือลดจำนวนข้อมูลที่เรียงลำดับ: นั่นคือการเรียงลำดับและ จำกัด ข้อมูลขั้นต่ำในเคียวรีย่อยจากนั้นเข้าร่วมกลับไปที่ตารางทั้งหมด
SELECT *
FROM wp_posts
INNER JOIN
(
SELECT max(post_date) post_date, post_author
FROM wp_posts
WHERE post_status='publish' AND post_type='post'
GROUP BY post_author
ORDER BY post_date DESC
-- LIMIT GOES HERE
) p2 USING (post_author, post_date)
WHERE post_status='publish' AND post_type='post';
แบบสอบถามเดียวกันโดยใช้วิธีการที่อธิบายข้างต้น:
SELECT *
FROM (
SELECT post_id
FROM wp_posts
WHERE post_status='publish' AND post_type='post'
GROUP BY post_author DESC
ORDER BY post_date DESC
-- LIMIT GOES HERE
) as ids
JOIN wp_posts USING (post_id);
ทุกคำสั่งผู้ที่มีแผนดำเนินการของพวกเขาในSQLFiddle
post_author
และpost_date
ไม่เพียงพอที่จะได้รับแถวที่ไม่ซ้ำกันดังนั้นจะต้องมีแถวที่ไม่ซ้ำกันต่อไปpost_author