<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.sqx.modules.creditRecord.dao.CreditRecordDao">

    <select id="getScore" resultType="com.sqx.modules.creditRecord.entity.CreditRecordEntity">
        SELECT
            this_month.create_time AS time,
            this_month.next_credit_score AS score,
            last_month.next_credit_score AS lscore,
            this_month.next_credit_score - last_month.next_credit_score AS diff
        FROM
        (
            (
            SELECT
                next_credit_score, create_time
            FROM credit_record
            WHERE rider_user_id = #{userId}
            AND is_driver = #{isDriver}
            ORDER BY create_time DESC
            LIMIT 1
            )
            UNION ALL
                ( SELECT 100 AS next_credit_score, NOW() AS create_time )
            LIMIT 1
        ) AS this_month,
        (
            SELECT IFNULL((
                SELECT next_credit_score
                FROM credit_record
                WHERE create_time &lt; DATE_FORMAT(CURDATE(), '%Y-%m-01')
                AND rider_user_id = #{userId}
                AND is_driver = #{isDriver}
                ORDER BY create_time DESC
                LIMIT 1
            ), 100) AS next_credit_score
        ) AS last_month
    </select>

    <select id="getFilledScore" resultType="com.sqx.modules.creditRecord.entity.CreditRecordMapEntity">
        <![CDATA[
        WITH RECURSIVE months AS (
          SELECT DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL #{several}-1 MONTH), '%Y-%m') AS month_val, 1 AS step
          UNION ALL
          SELECT DATE_FORMAT(DATE_ADD(DATE_SUB(CURDATE(), INTERVAL #{several}-1 MONTH), INTERVAL step MONTH), '%Y-%m'), step + 1
          FROM months
          WHERE step < #{several}
        ),
        latest_record_per_month AS (
          SELECT
            DATE_FORMAT(create_time, '%Y-%m') AS month,
            next_credit_score,
            create_time,
            ROW_NUMBER() OVER (PARTITION BY DATE_FORMAT(create_time, '%Y-%m') ORDER BY create_time DESC) AS rn
          FROM credit_record
          WHERE rider_user_id = #{userId}
            AND is_driver = #{isDriver}
        ),
        scores AS (
          SELECT month, next_credit_score
          FROM latest_record_per_month
          WHERE rn = 1
        ),
        first_month AS (
          SELECT MIN(month_val) AS month_val FROM months
        ),
        fallback_score AS (
          SELECT next_credit_score
          FROM credit_record
          WHERE rider_user_id = #{userId}
            AND is_driver = #{isDriver}
            AND create_time < CONCAT((SELECT month_val FROM first_month), '-01 00:00:00')
          ORDER BY create_time DESC
          LIMIT 1
        ),
        merged_scores AS (
          SELECT
            m.month_val AS month,
            CASE
              WHEN s.next_credit_score IS NOT NULL THEN s.next_credit_score
              WHEN m.month_val = (SELECT month_val FROM first_month) THEN (
                SELECT COALESCE(next_credit_score, 100) FROM fallback_score
                UNION ALL SELECT 100 LIMIT 1
              )
              ELSE NULL
            END AS next_credit_score
          FROM months m
          LEFT JOIN scores s ON m.month_val = s.month
        )
        SELECT
          month,
          CAST(@score := IFNULL(next_credit_score, @score) AS SIGNED) AS filled_score
        FROM merged_scores, (SELECT @score := NULL) vars
        ORDER BY month
      ]]>
    </select>

</mapper>