如何在现有SQL结构中实现按参考值分组前5行求和+其余行按1累加?
Solution to Extend Your SQL for Total Weight Calculation
Absolutely, you can expand your existing SQL structure to meet this requirement! Let's refactor and extend the code to handle both the top 5 Approved rows (summing their actual weights) and all other rows (counting each as 1), while retaining the Details summary you had before.
Adjusted SQL Query
SELECT wsf_ref, SUM(weight_contribution) AS Total_Weight, GROUP_CONCAT(DISTINCT CONCAT('TOP 5 ', type, ' (', top5_sum, ')') SEPARATOR ' ') AS Details FROM ( SELECT i.wsf_ref, i.type, -- Calculate contribution per row: use weight if Approved and top 5, else use 1 CASE WHEN r.rn <= 5 THEN i.weight ELSE 1 END AS weight_contribution, -- Pull the precomputed top 5 sum for each wsf_ref+type group for the Details field MAX(r.top5_sum) OVER (PARTITION BY i.wsf_ref, i.type) AS top5_sum FROM individual i LEFT JOIN ( -- Rank Approved rows per wsf_ref+type and compute the top 5 weight sum SELECT id, wsf_ref, type, CASE WHEN @prev_wsf = wsf_ref AND @prev_type = type THEN @row_num := @row_num + 1 ELSE @row_num := 1 END AS rn, -- Calculate total weight for top 5 rows in the group SUM(CASE WHEN @row_num <= 5 THEN weight ELSE 0 END) OVER (PARTITION BY wsf_ref, type) AS top5_sum, @prev_wsf := wsf_ref, @prev_type := type FROM individual CROSS JOIN (SELECT @row_num := 1, @prev_wsf := '', @prev_type := '') AS vars WHERE status = 'Approved' ORDER BY wsf_ref, type, id ASC ) r ON i.id = r.id ) AS all_rows GROUP BY wsf_ref ORDER BY Total_Weight DESC;
How This Works
Let's break down the key parts:
- Ranking Approved Rows: The inner subquery
rassigns a row number to eachApprovedrow within itswsf_ref+typegroup, and precomputes the total weight of the top 5 rows (top5_sum) for each group. This replaces your repetitiveUNION ALLblocks with a single, maintainable subquery. - Calculating Row Contributions: For every row in the
individualtable:- If it's an
Approvedrow and falls in the top 5 of its group, we use its actualweightas the contribution. - All other rows (Approved rows beyond the top 5, plus any non-Approved rows) contribute a value of 1.
- If it's an
- Final Aggregation: We group by
wsf_refto sum all contributions intoTotal_Weight, and useGROUP_CONCATto build theDetailssummary showing each type's top 5 weight total.
Verification Against Your Sample Data
- For
wsf_ref = 1:- Pike group: 5 rows ×10 =50, plus 1 extra row counted as 1 → total 51
- Asp group: 5 rows ×10=50, plus 1 extra row counted as1 → total51
- Combined total: 51+51=102 (matches your expected result)
- For
wsf_ref=2:- Only 1 Approved Pike row (top 5 eligible) → contribution of10 (matches your expected result)
内容的提问来源于stack exchange,提问作者Mark Harraway
相关产品推荐
相关产品推荐

