chengf
2025-08-25 bf3924206b359d77e928255328f8625cb986bd72
java110-db/src/main/resources/mapper/fee/ReportFeeServiceDaoImplMapper.xml
@@ -175,8 +175,8 @@
        row24 as row23,
        row25 as row24,
        row26 as row25,
        null as row26;
        null as row27;
        null as row26,
        null as row27,
        row27 as row28,
        null as row29,
        null as row30
@@ -258,4 +258,207 @@
            LIMIT #{pageNum}, #{pageSize}
        </if>
    </select>
    <select id="sss">
        WITH year_series AS (
            -- 生成2016-2025年序列(独立CTE便于复用)
            SELECT 2016 + n AS year
            FROM (
                     SELECT 0 AS n UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4
                     UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
                 ) AS nums
        ),
             all_data AS (
                 SELECT
                     pf.fee_id AS 费用编号,
                     pfc.fee_name AS 费用名称,
                     ys.year AS 年份,
                     -- 计算当年有效时间范围(1月1日至12月31日)
                     STR_TO_DATE(CONCAT(ys.year, '-01-01'), '%Y-%m-%d') AS 当年起始日,
                     STR_TO_DATE(CONCAT(ys.year, '-12-31'), '%Y-%m-%d') AS 当年截止日,
                     -- 已收区间(严格限定在当年范围内)
                     CASE
                         -- 费用起始时间晚于当年年底:无已收
                         WHEN pf.start_time > STR_TO_DATE(CONCAT(ys.year, '-12-31'), '%Y-%m-%d') THEN NULL
                         -- 费用截止时间早于当年年初:无已收
                         WHEN pf.end_time &lt; STR_TO_DATE(CONCAT(ys.year, '-01-01'), '%Y-%m-%d') THEN NULL
                         -- 正常情况:取重叠区间
                         ELSE GREATEST(pf.start_time, STR_TO_DATE(CONCAT(ys.year, '-01-01'), '%Y-%m-%d'))
                         END AS 当年已收起始日,
                     CASE
                         WHEN pf.start_time > STR_TO_DATE(CONCAT(ys.year, '-12-31'), '%Y-%m-%d') THEN NULL
                         WHEN pf.end_time &lt; STR_TO_DATE(CONCAT(ys.year, '-01-01'), '%Y-%m-%d') THEN NULL
                         ELSE LEAST(pf.end_time, STR_TO_DATE(CONCAT(ys.year, '-12-31'), '%Y-%m-%d'))
                         END AS 当年已收截止日,
                     -- 未收区间(严格限定在当年范围内)
                     CASE
                         -- 应缴截止时间早于当年年初:无未收
                         WHEN STR_TO_DATE(pfa.`value`, '%Y-%m-%d') &lt; STR_TO_DATE(CONCAT(ys.year, '-01-01'), '%Y-%m-%d') THEN NULL
                         -- 费用截止时间晚于当年年底:无未收
                         WHEN pf.end_time > STR_TO_DATE(CONCAT(ys.year, '-12-31'), '%Y-%m-%d') THEN NULL
                         -- 正常情况:取重叠区间
                         ELSE GREATEST(pf.end_time, STR_TO_DATE(CONCAT(ys.year, '-01-01'), '%Y-%m-%d'))
                         END AS 当年未收起始日,
                     CASE
                         WHEN STR_TO_DATE(pfa.`value`, '%Y-%m-%d') &lt; STR_TO_DATE(CONCAT(ys.year, '-01-01'), '%Y-%m-%d') THEN NULL
                         WHEN pf.end_time > STR_TO_DATE(CONCAT(ys.year, '-12-31'), '%Y-%m-%d') THEN NULL
                         ELSE LEAST(STR_TO_DATE(pfa.`value`, '%Y-%m-%d'), STR_TO_DATE(CONCAT(ys.year, '-12-31'), '%Y-%m-%d'))
                         END AS 当年未收截止日,
                     -- 已收月数(仅统计当年的有效明细)
                     COALESCE(COUNT(DISTINCT CASE
                                                 WHEN pfdm.detail_year = ys.year AND pfdm.status_cd = '0'
                                                     THEN CONCAT(pfdm.detail_year, '-', LPAD(pfdm.detail_month, 2, '0'))
                         END), 0) AS 当年已收月数,
                     -- 应收月数(当年内的理论应收月数)
                     CASE
                         WHEN GREATEST(pf.start_time, STR_TO_DATE(CONCAT(ys.year, '-01-01'), '%Y-%m-%d')) >
                              LEAST(STR_TO_DATE(pfa.`value`, '%Y-%m-%d'), STR_TO_DATE(CONCAT(ys.year, '-12-31'), '%Y-%m-%d'))
                             THEN 0
                         ELSE TIMESTAMPDIFF(
                                      MONTH,
                                      GREATEST(pf.start_time, STR_TO_DATE(CONCAT(ys.year, '-01-01'), '%Y-%m-%d')),
                                      LEAST(STR_TO_DATE(pfa.`value`, '%Y-%m-%d'), STR_TO_DATE(CONCAT(ys.year, '-12-31'), '%Y-%m-%d'))
                              ) + 1
                         END AS 当年应收月数,
                     -- 计算每月费用(单价×面积)
                     pfc.square_price * br.built_up_area AS 每月费用,
                     -- 折扣金额(仅统计当年的有效折扣)
                     COALESCE(SUM(CASE WHEN pfdm.detail_year = ys.year THEN pfdm.discount_amount ELSE 0 END), 0) AS 当年折扣金额
                 FROM pay_fee pf
                          INNER JOIN pay_fee_config pfc
                                     ON pf.config_id = pfc.config_id
                                         AND pfc.square_price > 0  -- 确保有有效单价
                          INNER JOIN building_room br
                                     ON pf.payer_obj_id = br.room_id
                          INNER JOIN pay_fee_attrs pfa
                                     ON pf.fee_id = pfa.fee_id
                                         AND pfa.spec_cd = '390010'  -- 应缴截止日期属性
                          INNER JOIN year_series ys ON 1=1  -- 关联年份序列
                          LEFT JOIN pay_fee_detail_month pfdm
                                    ON pf.fee_id = pfdm.fee_id
                                        AND pfdm.obj_id = pf.payer_obj_id
                                        AND pfdm.status_cd = '0'  -- 有效明细
                 WHERE pf.payer_obj_id = '752025071562520009'
                   AND pf.fee_type_cd IN ('630000001', '630000002')
                   AND pf.status_cd = '0'  -- 有效费用
                 GROUP BY
                     pf.fee_id, pfc.fee_name, ys.year,
                     pf.start_time, pf.end_time, pfa.`value`,
                     pfc.square_price, br.built_up_area
             ),
             calculated_data AS (
                 -- 计算金额字段(基于已收/应收月数)
                 SELECT
                     费用编号,
                     费用名称,
                     年份,
                     当年已收起始日,
                     当年已收截止日,
                     当年未收起始日,
                     当年未收截止日,
                     当年已收月数,
                     当年应收月数,
                     每月费用,
                     当年折扣金额,
                     -- 应收金额=应收月数×每月费用
                     当年应收月数 * 每月费用 AS 当年应收金额,
                     -- 实收金额=已收月数×每月费用-折扣金额
                     (当年已收月数 * 每月费用) - 当年折扣金额 AS 当年实收金额
                 FROM all_data
             ),
             grouped_data AS (
                 -- 各年份数据
                 SELECT
                     费用编号,
                     费用名称,
                     CONCAT(年份, '年') AS 统计维度,
                     年份 AS 排序辅助,
                     当年已收月数 AS 已收月数,
                     -- 已收区间(仅显示有效区间)
                     CASE
                         WHEN 当年已收起始日 IS NOT NULL AND 当年已收截止日 IS NOT NULL
                             THEN CONCAT(DATE_FORMAT(当年已收起始日, '%Y-%m-%d'), ' ~ ', DATE_FORMAT(当年已收截止日, '%Y-%m-%d'))
                         ELSE NULL
                         END AS 已收区间,
                     -- 未收区间(仅显示有效区间)
                     CASE
                         WHEN 当年未收起始日 IS NOT NULL AND 当年未收截止日 IS NOT NULL
                             THEN CONCAT(DATE_FORMAT(当年未收起始日, '%Y-%m-%d'), ' ~ ', DATE_FORMAT(当年未收截止日, '%Y-%m-%d'))
                         ELSE NULL
                         END AS 未收区间,
                     当年应收金额 AS 应收金额,
                     当年实收金额 AS 实收金额,
                     当年折扣金额 AS 折扣金额
                 FROM calculated_data
                 WHERE 年份 BETWEEN 2016 AND 2025
                 UNION ALL
                 -- 2020年单独统计
                 SELECT
                     费用编号,
                     费用名称,
                     '2020年' AS 统计维度,
                     2020 AS 排序辅助,
                     SUM(当年已收月数) AS 已收月数,
                     CASE
                         WHEN MIN(当年已收起始日) IS NOT NULL AND MAX(当年已收截止日) IS NOT NULL
                             THEN CONCAT(DATE_FORMAT(MIN(当年已收起始日), '%Y-%m-%d'), ' ~ ', DATE_FORMAT(MAX(当年已收截止日), '%Y-%m-%d'))
                         ELSE NULL
                         END AS 已收区间,
                     CASE
                         WHEN MIN(当年未收起始日) IS NOT NULL AND MAX(当年未收截止日) IS NOT NULL
                             THEN CONCAT(DATE_FORMAT(MIN(当年未收起始日), '%Y-%m-%d'), ' ~ ', DATE_FORMAT(MAX(当年未收截止日), '%Y-%m-%d'))
                         ELSE NULL
                         END AS 未收区间,
                     SUM(当年应收金额) AS 应收金额,
                     SUM(当年实收金额) AS 实收金额,
                     SUM(当年折扣金额) AS 折扣金额
                 FROM calculated_data
                 WHERE 年份 = 2020
                 GROUP BY 费用编号, 费用名称, 统计维度, 排序辅助
                 UNION ALL
                 -- 2016-2025年合计
                 SELECT
                     费用编号,
                     费用名称,
                     '2016-2025年合计' AS 统计维度,
                     9999 AS 排序辅助,
                     SUM(当年已收月数) AS 已收月数,
                     CASE
                         WHEN MIN(当年已收起始日) IS NOT NULL AND MAX(当年已收截止日) IS NOT NULL
                             THEN CONCAT(DATE_FORMAT(MIN(当年已收起始日), '%Y-%m-%d'), ' ~ ', DATE_FORMAT(MAX(当年已收截止日), '%Y-%m-%d'))
                         ELSE NULL
                         END AS 已收区间,
                     CASE
                         WHEN MIN(当年未收起始日) IS NOT NULL AND MAX(当年未收截止日) IS NOT NULL
                             THEN CONCAT(DATE_FORMAT(MIN(当年未收起始日), '%Y-%m-%d'), ' ~ ', DATE_FORMAT(MAX(当年未收截止日), '%Y-%m-%d'))
                         ELSE NULL
                         END AS 未收区间,
                     SUM(当年应收金额) AS 应收金额,
                     SUM(当年实收金额) AS 实收金额,
                     SUM(当年折扣金额) AS 折扣金额
                 FROM calculated_data
                 WHERE 年份 BETWEEN 2016 AND 2025
                 GROUP BY 费用编号, 费用名称, 统计维度, 排序辅助
             )
-- 最终结果输出
        SELECT
            费用编号,
            费用名称,
            统计维度,
            已收月数,
            已收区间,
            未收区间,
            应收金额,
            实收金额,
            折扣金额
        FROM grouped_data where 应收金额 != 0
        ORDER BY
            费用编号,
            排序辅助;
    </select>
</mapper>