आपकी दूसरी क्वेरी फ़ॉर्म की है:
q1 -- PK user_id
LEFT JOIN (...
GROUP BY user_id, t.tag
) AS q2
ON q2.user_id = q1.user_id
LEFT JOIN (...
GROUP BY user_id, c.category
) AS q3
ON q3.user_id = q1.user_id
GROUP BY -- group_concats
आंतरिक GROUP BY का परिणाम (user_id, t.tag)
होता है &(user_id, c.category)
कुंजी/अद्वितीय होने के नाते। इसके अलावा मैं उन ग्रुप बाय को संबोधित नहीं करूंगा।
TL;DR जब आप (q1 JOIN q2) से q3 में शामिल होते हैं तो यह उनमें से किसी एक की कुंजी/अद्वितीय पर नहीं होता है, इसलिए प्रत्येक user_id के लिए आपको टैग और श्रेणी के हर संभावित संयोजन के लिए एक पंक्ति मिलती है। तो अंतिम ग्रुप बाय इनपुट डुप्लिकेट प्रति (user_id, टैग) और प्रति (user_id, श्रेणी) और अनुपयुक्त रूप से GROUP_CONCATs डुप्लिकेट टैग और श्रेणियां प्रति user_id। सही होगा (क्यू1 क्यू2 ग्रुप बाय से जुड़ें) जॉइन करें (क्यू1 क्यू3 ग्रुप बाय में शामिल हों) जिसमें सभी जॉइन कॉमन की/यूनिक (user_id)
पर हों। और कोई नकली एकत्रीकरण नहीं है। हालांकि कभी-कभी आप ऐसे नकली एकत्रीकरण को पूर्ववत कर सकते हैं।
एक सही सममित INNER JOIN दृष्टिकोण:LEFT JOIN q1 और q2--1:कई - फिर GROUP BY और GROUP_CONCAT (जो आपकी पहली क्वेरी है); फिर अलग से इसी तरह LEFT JOIN q1 &q3--1:कई--फिर GROUP BY &GROUP_CONCAT; फिर user_id--1:1 पर दो परिणामों में शामिल हों।
एक सही सममित स्केलर सबक्वेरी दृष्टिकोण:q1 से GROUP_CONCATs को स्केलर सबक्वेरी के रूप में चुनें। प्रत्येक समूह के साथ।
एक सही संचयी LEFT JOIN दृष्टिकोण:LEFT JOIN q1 &q2--1:कई--फिर GROUP BY &GROUP_CONCAT; फिर बाएँ उसमें शामिल हों और q3--1:कई--फिर GROUP BY और GROUP_CONCAT।
आपकी दूसरी क्वेरी की तरह एक सही दृष्टिकोण:आप पहले q1 और q2--1:कई में शामिल हों। फिर आप उस और q3 में शामिल हों - कई:1:कई। यह एक टैग और एक श्रेणी के हर संभव संयोजन के लिए एक पंक्ति देता है जो एक user_id के साथ दिखाई देता है। फिर आपके द्वारा GROUP BY GROUP_CONCAT के बाद - डुप्लिकेट (user_id, टैग) जोड़े और डुप्लिकेट (user_id, श्रेणी) जोड़े पर। यही कारण है कि आपके पास डुप्लिकेट सूची तत्व हैं। लेकिन DISTINCT को GROUP_CONCAT में जोड़ने से सही परिणाम मिलता है। (प्रति wchiquito की टिप्पणी।)
जो आप पसंद करते हैं वह सामान्य रूप से एक इंजीनियरिंग ट्रेडऑफ़ है जिसे वास्तविक डेटा/उपयोग/सांख्यिकी के अनुसार क्वेरी योजनाओं और समय द्वारा सूचित किया जाना है। दोहराव की अपेक्षित मात्रा के लिए इनपुट और आंकड़े), वास्तविक प्रश्नों का समय, आदि। एक मुद्दा यह है कि क्या कई की अतिरिक्त पंक्तियां:1:कई जॉइन दृष्टिकोण ग्रुप बाय की बचत को ऑफसेट करते हैं।
-- cumulative LEFT JOIN approach
SELECT
q1.user_id, q1.user_name, q1.score, q1.reputation,
top_two_tags,
substring_index(group_concat(q3.category ORDER BY q3.category_reputation DESC SEPARATOR ','), ',', 2) AS category
FROM
-- your 1st query (less ORDER BY) AS q1
(SELECT
q1.user_id, q1.user_name, q1.score, q1.reputation,
substring_index(group_concat(q2.tag ORDER BY q2.tag_reputation DESC SEPARATOR ','), ',', 2) AS top_two_tags
FROM
(SELECT
u.id AS user_Id,
u.user_name,
coalesce(sum(r.score), 0) as score,
coalesce(sum(r.reputation), 0) as reputation
FROM
users u
LEFT JOIN reputations r
ON r.user_id = u.id
AND r.date_time > 1500584821 /* unix_timestamp(DATE_SUB(now(), INTERVAL 1 WEEK)) */
GROUP BY
u.id, u.user_name
) AS q1
LEFT JOIN
(
SELECT
r.user_id AS user_id, t.tag, sum(r.reputation) AS tag_reputation
FROM
reputations r
JOIN post_tag pt ON pt.post_id = r.post_id
JOIN tags t ON t.id = pt.tag_id
WHERE
r.date_time > 1500584821 /* unix_timestamp(DATE_SUB(now(), INTERVAL 1 WEEK)) */
GROUP BY
user_id, t.tag
) AS q2
ON q2.user_id = q1.user_id
GROUP BY
q1.user_id, q1.user_name, q1.score, q1.reputation
) AS q1
-- finish like your 2nd query
LEFT JOIN
(
SELECT
r.user_id AS user_id, c.category, sum(r.reputation) AS category_reputation
FROM
reputations r
JOIN post_category ct ON ct.post_id = r.post_id
JOIN categories c ON c.id = ct.category_id
WHERE
r.date_time > 1500584821 /* unix_timestamp(DATE_SUB(now(), INTERVAL 1 WEEK)) */
GROUP BY
user_id, c.category
) AS q3
ON q3.user_id = q1.user_id
GROUP BY
q1.user_id, q1.user_name, q1.score, q1.reputation
ORDER BY
q1.reputation DESC, q1.score DESC ;