如何对这个SQL进行分组

时间:2018-11-09 17:13:19

标签: mysql sql

下面的SQL语句产生几个月的数据总和,并将列显示为年。

问题如下图所示,结果是结果集为空值。有没有一种方法可以表示每个月一次的数据集?

SELECT 
    DATE_FORMAT(start_date, '%M') AS M,
    (CASE DATE_FORMAT(start_date, '%Y')
        WHEN
            2015
        THEN
            ROUND((COALESCE(SUM(b.bid_amount), 0) + COALESCE(SUM(b.hourly_bid_amount), 0) + COALESCE(SUM(b.other_bid_amount), 0) * pcntg.percentage / 100 + SUM(b.other_bid_amount) - COALESCE(SUM(b.subcontracted_amount), 0)),
                    2) + COALESCE(SUM(b.subcontracted_amount), 0) + COALESCE(SUM(b.contingency_1), 0)
    END) AS '2015',
    (CASE DATE_FORMAT(start_date, '%Y')
        WHEN
            2016
        THEN
            ROUND((COALESCE(SUM(b.bid_amount), 0) + COALESCE(SUM(b.hourly_bid_amount), 0) + COALESCE(SUM(b.other_bid_amount), 0) * pcntg.percentage / 100 + SUM(b.other_bid_amount) - COALESCE(SUM(b.subcontracted_amount), 0)),
                    2) + COALESCE(SUM(b.subcontracted_amount), 0) + COALESCE(SUM(b.contingency_1), 0)
    END) AS '2016',
    (CASE DATE_FORMAT(start_date, '%Y')
        WHEN
            2017
        THEN
            ROUND((COALESCE(SUM(b.bid_amount), 0) + COALESCE(SUM(b.hourly_bid_amount), 0) + COALESCE(SUM(b.other_bid_amount), 0) * pcntg.percentage / 100 + SUM(b.other_bid_amount) - COALESCE(SUM(b.subcontracted_amount), 0)),
                    2) + COALESCE(SUM(b.subcontracted_amount), 0) + COALESCE(SUM(b.contingency_1), 0)
    END) AS '2017',
    (CASE DATE_FORMAT(start_date, '%Y')
        WHEN
            2018
        THEN
            ROUND((COALESCE(SUM(b.bid_amount), 0) + COALESCE(SUM(b.hourly_bid_amount), 0) + COALESCE(SUM(b.other_bid_amount), 0) * pcntg.percentage / 100 + SUM(b.other_bid_amount) - COALESCE(SUM(b.subcontracted_amount), 0)),
                    2) + COALESCE(SUM(b.subcontracted_amount), 0) + COALESCE(SUM(b.contingency_1), 0)
    END) AS '2018'
FROM
    phases_required b
        RIGHT JOIN
    projects a ON b.project_id = a.id
        LEFT JOIN
    (SELECT 
        t2.project_id, ROUND(reimbursable_percent, 0) AS percentage
    FROM
        rate_names t1, phases_required t2, rates_phase t3
    WHERE
        t1.id = t3.rate_names_id
            AND t3.rates_id = t2.rates_id
    GROUP BY t2.project_id) AS pcntg ON pcntg.project_id = a.id
WHERE
    start_date != '0000-00-00'
        AND DATE_FORMAT(start_date, '%Y') NOT IN (2010 , 2012, 2013, 2014)
GROUP by DATE_FORMAT(start_date, '%m%Y')  

Result Set

以下是用于动态生成您在上面看到的表SQL语句的SQL:

SET SESSION group_concat_max_len = 10000000000;
SET @sqldynamic = (

SELECT 
GROUP_CONCAT( distinct

CONCAT( '(case date_format(start_date,"%Y") when ', date_format(a.start_date,"%Y") , ' then ROUND((COALESCE(sum(b.bid_amount), 0) + COALESCE(sum(b.hourly_bid_amount),0) + COALESCE(sum(b.other_bid_amount), 0) * pcntg.percentage/100 + sum(b.other_bid_amount) - COALESCE(sum(b.subcontracted_amount),0)),2)+COALESCE(sum(b.subcontracted_amount),0)+COALESCE(sum(b.contingency_1),0) end) as \'' , date_format(start_date,"%Y"),'\''
        )
    )
From phases_required b RIGHT JOIN projects a  ON b.project_id = a.id LEFT JOIN (SELECT t2.project_id, round(reimbursable_percent,0) as percentage FROM rate_names t1,phases_required t2,rates_phase t3
WHERE t1.id = t3.rate_names_id AND t3.rates_id = t2.rates_id group by t2.project_id) as pcntg on pcntg.project_id =a.id
WHERE start_date != "0000-00-00" and date_format(start_date,"%Y") not in (2010,2012,2013,2014) 
);




SET @sql = CONCAT('SELECT date_format(start_date,"%M") as M, ', 
        @sqldynamic, ' 
    From phases_required b RIGHT JOIN projects a  ON b.project_id = a.id LEFT JOIN (SELECT t2.project_id, round(reimbursable_percent,0) as percentage FROM rate_names t1,phases_required t2,rates_phase t3
WHERE t1.id = t3.rate_names_id AND t3.rates_id = t2.rates_id group by t2.project_id) as pcntg on pcntg.project_id =a.id
WHERE start_date != "0000-00-00" and date_format(start_date,"%Y") not in (2010,2012,2013,2014)
group by date_format(start_date,"%M%Y") order by date_format(start_date,"%m")'
);


PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

2 个答案:

答案 0 :(得分:0)

我不喜欢,但它应该可以工作:

select m,
sum(coalesce('2015', 0)) '2015',
sum(coalesce('2015', 0)) '2016', 
sum(coalesce('2015', 0)) '2017', 
sum(coalesce('2015', 0)) '2018' 
from (
SELECT 
    DATE_FORMAT(start_date, '%M') AS M,
    (CASE DATE_FORMAT(start_date, '%Y')
        WHEN
            2015
        THEN
            ROUND((COALESCE(SUM(b.bid_amount), 0) + COALESCE(SUM(b.hourly_bid_amount), 0) + COALESCE(SUM(b.other_bid_amount), 0) * pcntg.percentage / 100 + SUM(b.other_bid_amount) - COALESCE(SUM(b.subcontracted_amount), 0)),
                    2) + COALESCE(SUM(b.subcontracted_amount), 0) + COALESCE(SUM(b.contingency_1), 0)
    END) AS '2015',
    (CASE DATE_FORMAT(start_date, '%Y')
        WHEN
            2016
        THEN
            ROUND((COALESCE(SUM(b.bid_amount), 0) + COALESCE(SUM(b.hourly_bid_amount), 0) + COALESCE(SUM(b.other_bid_amount), 0) * pcntg.percentage / 100 + SUM(b.other_bid_amount) - COALESCE(SUM(b.subcontracted_amount), 0)),
                    2) + COALESCE(SUM(b.subcontracted_amount), 0) + COALESCE(SUM(b.contingency_1), 0)
    END) AS '2016',
    (CASE DATE_FORMAT(start_date, '%Y')
        WHEN
            2017
        THEN
            ROUND((COALESCE(SUM(b.bid_amount), 0) + COALESCE(SUM(b.hourly_bid_amount), 0) + COALESCE(SUM(b.other_bid_amount), 0) * pcntg.percentage / 100 + SUM(b.other_bid_amount) - COALESCE(SUM(b.subcontracted_amount), 0)),
                    2) + COALESCE(SUM(b.subcontracted_amount), 0) + COALESCE(SUM(b.contingency_1), 0)
    END) AS '2017',
    (CASE DATE_FORMAT(start_date, '%Y')
        WHEN
            2018
        THEN
            ROUND((COALESCE(SUM(b.bid_amount), 0) + COALESCE(SUM(b.hourly_bid_amount), 0) + COALESCE(SUM(b.other_bid_amount), 0) * pcntg.percentage / 100 + SUM(b.other_bid_amount) - COALESCE(SUM(b.subcontracted_amount), 0)),
                    2) + COALESCE(SUM(b.subcontracted_amount), 0) + COALESCE(SUM(b.contingency_1), 0)
    END) AS '2018'
FROM
    phases_required b
        RIGHT JOIN
    projects a ON b.project_id = a.id
        LEFT JOIN
    (SELECT 
        t2.project_id, ROUND(reimbursable_percent, 0) AS percentage
    FROM
        rate_names t1, phases_required t2, rates_phase t3
    WHERE
        t1.id = t3.rate_names_id
            AND t3.rates_id = t2.rates_id
    GROUP BY t2.project_id) AS pcntg ON pcntg.project_id = a.id
WHERE
    start_date != '0000-00-00'
        AND DATE_FORMAT(start_date, '%Y') NOT IN (2010 , 2012, 2013, 2014)
GROUP by DATE_FORMAT(start_date, '%m%Y') 
) qry
group by m;

答案 1 :(得分:0)

这是答案。谢谢Daniel Blais帮助我到达这里。

SET SESSION group_concat_max_len = 10000000000;
SET @sqldynamic = (

SELECT 
GROUP_CONCAT( distinct

CONCAT( '(case date_format(start_date,"%Y") when ', date_format(a.start_date,"%Y") , ' then ROUND((COALESCE(sum(b.bid_amount), 0) + COALESCE(sum(b.hourly_bid_amount),0) + COALESCE(sum(b.other_bid_amount), 0) * pcntg.percentage/100 + sum(b.other_bid_amount) - COALESCE(sum(b.subcontracted_amount),0)),2)+COALESCE(sum(b.subcontracted_amount),0)+COALESCE(sum(b.contingency_1),0) end) as Y_' , date_format(start_date,"%Y")
        )
    )
From phases_required b RIGHT JOIN projects a  ON b.project_id = a.id LEFT JOIN (SELECT t2.project_id, round(reimbursable_percent,0) as percentage FROM rate_names t1,phases_required t2,rates_phase t3
WHERE t1.id = t3.rate_names_id AND t3.rates_id = t2.rates_id group by t2.project_id) as pcntg on pcntg.project_id =a.id
WHERE start_date != "0000-00-00" and date_format(start_date,"%Y") not in (2010,2012,2013,2014) 
);

SET @sqlgroup = (
SELECT 
GROUP_CONCAT(distinct

CONCAT('sum(coalesce(Y_', date_format(a.start_date,"%Y") ,', 0)) as Y_',date_format(a.start_date,"%Y")
        )
    )
From phases_required b RIGHT JOIN projects a  ON b.project_id = a.id LEFT JOIN (SELECT t2.project_id, round(reimbursable_percent,0) as percentage FROM rate_names t1,phases_required t2,rates_phase t3
WHERE t1.id = t3.rate_names_id AND t3.rates_id = t2.rates_id group by t2.project_id) as pcntg on pcntg.project_id =a.id
WHERE start_date != "0000-00-00" and date_format(start_date,"%Y") not in (2010,2012,2013,2014) 

);



SET @sql = CONCAT('select m,', @sqlgroup , ' from (SELECT date_format(start_date,"%M") as M, date_format(start_date,"%m") as m2 ,', 
        @sqldynamic, ' 
    From phases_required b RIGHT JOIN projects a  ON b.project_id = a.id LEFT JOIN (SELECT t2.project_id, round(reimbursable_percent,0) as percentage FROM rate_names t1,phases_required t2,rates_phase t3
WHERE t1.id = t3.rate_names_id AND t3.rates_id = t2.rates_id group by t2.project_id) as pcntg on pcntg.project_id =a.id
WHERE start_date != "0000-00-00" and date_format(start_date,"%Y") not in (2010,2012,2013,2014)
group by date_format(start_date,"%M%Y") order by date_format(start_date,"%m")) qry group by m order by m2'
);



PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;