我正在处理包含嵌套选择语句的 SQL 查询。我需要修改它,以便根据某些条件,将“历史代码”中右侧的第一个非零值替换为一系列连续数字。
例如,如果历史代码是0302230,我想将其转换为0302232100。在这个例子中,3(右侧第一个非零值)被替换为3210,结果是03022(3210)0 .
历史代码逻辑取决于涉及两个日期的条件:paidAt和deadlineDate。 根据历史代码中第一个非零出现的值进行转换。逻辑总结如下:
如果右侧第一个非零数字是 1,则将其替换为 10。 如果是2,则替换为210。 如果是 3,则将其替换为 3210,依此类推,直至: 如果是6,则替换为6543210。 如果是W,则更换为W6543210。 并附加其余的历史代码
下面是我当前正在使用的 SQL 代码:
SELECT
GROUP_CONCAT(
CASE
WHEN i.paidAt IS NULL
AND DATE_ADD(i.deadlineDate, INTERVAL 10 DAY) < CURDATE()
AND i.dueDate = (
SELECT MIN(i2.dueDate)
FROM installment i2
WHERE i2.contractId = i.contractId
AND i2.paidAt IS NULL
AND DATE_ADD(i2.deadlineDate, INTERVAL 10 DAY) < CURDATE()
LIMIT 1
)
THEN
CASE
WHEN DATEDIFF(CURDATE(), DATE_ADD(i.deadlineDate, INTERVAL 10 DAY)) <= 0 THEN '0'
WHEN DATEDIFF(CURDATE(), DATE_ADD(i.deadlineDate, INTERVAL 10 DAY)) BETWEEN 1 AND 29 THEN '1'
WHEN DATEDIFF(CURDATE(), DATE_ADD(i.deadlineDate, INTERVAL 10 DAY)) BETWEEN 30 AND 59 THEN '2'
WHEN DATEDIFF(CURDATE(), DATE_ADD(i.deadlineDate, INTERVAL 10 DAY)) BETWEEN 60 AND 89 THEN '3'
WHEN DATEDIFF(CURDATE(), DATE_ADD(i.deadlineDate, INTERVAL 10 DAY)) BETWEEN 90 AND 119 THEN '4'
WHEN DATEDIFF(CURDATE(), DATE_ADD(i.deadlineDate, INTERVAL 10 DAY)) BETWEEN 120 AND 149 THEN '5'
WHEN DATEDIFF(CURDATE(), DATE_ADD(i.deadlineDate, INTERVAL 10 DAY)) BETWEEN 150 AND 179 THEN '6'
WHEN DATEDIFF(CURDATE(), DATE_ADD(i.deadlineDate, INTERVAL 10 DAY)) >= 180 THEN 'W'
END
ELSE
CASE
WHEN DATEDIFF(i.paidAt, DATE_ADD(i.deadlineDate, INTERVAL 10 DAY)) <= 0 THEN '0'
WHEN DATEDIFF(i.paidAt, DATE_ADD(i.deadlineDate, INTERVAL 10 DAY)) BETWEEN 1 AND 29 THEN '1'
WHEN DATEDIFF(i.paidAt, DATE_ADD(i.deadlineDate, INTERVAL 10 DAY)) BETWEEN 30 AND 59 THEN '2'
WHEN DATEDIFF(i.paidAt, DATE_ADD(i.deadlineDate, INTERVAL 10 DAY)) BETWEEN 60 AND 89 THEN '3'
WHEN DATEDIFF(i.paidAt, DATE_ADD(i.deadlineDate, INTERVAL 10 DAY)) BETWEEN 90 AND 119 THEN '4'
WHEN DATEDIFF(i.paidAt, DATE_ADD(i.deadlineDate, INTERVAL 10 DAY)) BETWEEN 120 AND 149 THEN '5'
WHEN DATEDIFF(i.paidAt, DATE_ADD(i.deadlineDate, INTERVAL 10 DAY)) BETWEEN 150 AND 179 THEN '6'
WHEN DATEDIFF(i.paidAt, DATE_ADD(i.deadlineDate, INTERVAL 10 DAY)) >= 180 THEN 'W'
END
END ORDER BY i.dueDate DESC SEPARATOR ''
)
FROM installment i
WHERE i.contractId = [c.id](http://c.id/)
) AS 'Payment History Status Code',
有人可以帮我实现正确替换历史代码中右侧第一个非零值的逻辑吗?
r
你有 REGEXP_INSTR 吗?:
SELECT id, Historycode, char_length(HistoryCode),TargetCharPos,
case substring(HistoryCode, TargetCharPos , 1)
when '0' then HistoryCode
else concat(
left(HistoryCode, TargetCharPos-1),
case substring(HistoryCode, TargetCharPos , 1)
when '1' then '10'
when '2' then '210'
when '3' then '3210'
when '6' then '6543210'
end,
substring(HistoryCode,TargetCharPos+1)
)
end as NewHistoryCode
from ( SELECT id, Historycode, REGEXP_INSTR(HistoryCode, '[^0]0*$') as TargetCharPos FROM Tbl
) Step1
我们找到子查询中最后一个非零字符位置,然后在另一个查询中计算出替换值。