自定义变量的属性和限制
- 使用自定义变量的查询,无法使用查询缓存。
- 不能在使用常量或者标识列的地方使用自定义变量,例如表名、列明和LIMIT子句中。
- 用户自定义变量的生命周期是在一个连接中有效,所以不能使用它们来做连接间的通信。
- 如果使用连接池或者持久化连接,自定义变量可能让看起来毫无关系的代码发生交互。
- 在5.0版本之前,是大小写敏感的,所以要注意代码在不同版本之间的兼容性问题。
- 不能显示的声明自定义变量的类型。它是一个动态类型。整数初始化为0,浮点型初始化为0.0,字符串初始化为’’。
- MySQL优化器在某些场景下可能会将这些变量优化掉,这可能导致代码不按预想的方式运行。
- 赋值的顺序和赋值的时间点并不总是固定的,这依赖于优化器的决定。
- 赋值符号:=的优先级非常低,所有要注意赋值表达式应该使用明确的括号。
- 使用未定义变量不会产生任何错误,如果没有意识到这一点,非常容易犯错。
SET @applykey = 0, @loanRank = 0; SELECT applyId, custId, ruleVersion, rejectRule, STATUS , extra, createTime, updateTime, mobile , IF(STATUS = 1, IF(@applykey <> custId, @loanRank := 1, @loanRank := @loanRank + 1), '0') AS applyPassRank , @applykey := custId FROM ( SELECT applyId, custId, ruleVersion, rejectRule, STATUS , extra, createTime, updateTime, mobile FROM sync.credit_apply WHERE updateTime < '2019-11-27' ORDER BY custId, updateTime ) t;
SET @cfkkey = 0, @cfkRank = 0; SELECT cust_id, loan_amt_quota , IF(@cfkkey <> cust_id, @cfkRank := 1, @cfkRank := @cfkRank + 1) AS cfkRank , @cfkkey := cust_id FROM ( SELECT cust_id, loan_amt AS loan_amt_quota FROM sync.loandb_cfk_loan ORDER BY cust_id, create_time ) t
SET @applykey = 0, @loanRank = 0; SET @cfkkey = 0, @cfkRank = 0; CREATE TABLE test2 AS SELECT applyId, custId, ruleVersion, rejectRule, STATUS , extra, loan_amt_quota , IF(first_finish_loan_Time IS NULL, 1, IF(updateTime < first_finish_loan_Time, 1, 0)) AS is_new , createTime, updateTime, mobile, applyPassRank, cfk_Rank FROM ( SELECT applyId, custId, ruleVersion, rejectRule, STATUS , extra, createTime, updateTime, mobile , IF(STATUS = 1, IF(@applykey <> custId, @loanRank := 1, @loanRank := @loanRank + 1), '0') AS applyPassRank , @applykey := custId FROM ( SELECT applyId, custId, ruleVersion, rejectRule, STATUS , extra, createTime, updateTime, mobile FROM sync.credit_apply WHERE updateTime < '2019-11-27' ORDER BY custId, updateTime ) t ) apply LEFT JOIN ( SELECT cust_id , CASE WHEN locate('|', updateTime) > 0 THEN SUBSTR(updateTime, 1, INSTR(updateTime, '|') - 1) ELSE updateTime END AS first_finish_loan_Time FROM ( SELECT cust_id, GROUP_CONCAT(update_Time ORDER BY update_Time ASC SEPARATOR '|') AS updateTime FROM sync.loandb_cfk_loan WHERE (substr(update_Time, 1, 10) < '2019-11-27' AND loan_type = 'xxx' AND loan_status = 'yyy') GROUP BY cust_id ) t ) cfk_loan ON apply.custId = cfk_loan.cust_id LEFT JOIN ( SELECT cust_id, loan_amt_quota , IF(@cfkkey <> cust_id, @cfkRank := 1, @cfkRank := @cfkRank + 1) AS cfk_Rank , @cfkkey := cust_id FROM ( SELECT cust_id, loan_amt AS loan_amt_quota FROM sync.loandb_cfk_loan ORDER BY cust_id, create_time ) t ) quota ON apply.custId = quota.cust_id AND apply.applyPassRank = quota.cfk_Rank;
后来发现不是这个问题而是多加上一个排序字段就OK了:
SET @applykey := 0, @loanRank = 0; SELECT applyId, custId, ruleVersion, rejectRule, STATUS , extra, createTime, updateTime, mobile , IF(STATUS = 1, IF(@applykey <> custId, @loanRank := 1, @loanRank := @loanRank + 1), '0') AS applyPassRank , @applykey := custId FROM ( SELECT applyId, custId, ruleVersion, rejectRule, STATUS , extra, createTime, updateTime, mobile FROM sync.credit_apply WHERE updateTime < '2019-11-28' ORDER BY custId,STATUS, updateTime ) t HAVING custId=xxx33089