借鑒:mysql使用instr達到in(字符串)的效果
結論:select * from 表名where INSTR(CONCAT(字符串),CONCAT(表id))
問題來源:一表中的某字段是另一表的外鍵,該字段是外鍵表的id組成的字符串,如“1,2,3,4”這種形式,如何關聯查詢兩張表,根據外鍵id查詢另一張表呢?
該表的設計連第一范式都沒有實現,不能容忍!!!!!!!!!!!!!
表一:
表二:
首先想到的思路,對字符串進行遍歷查詢,但是mybatis中collection不接受string,所以我沒有實現這個思路。
<foreach collection="act_id.split(',')" open="(" separator="," close=")" item="item" >
#{item}
</foreach>
第二個思路,使用concat進行字符串拼接,如“1,2,3,4”轉化為(“1,2,3,4”),但是mysql where in 后不可以使用字符串,無法識別,這個思路也沒有實現。
第三個思路,使用instr達到in(字符串)的效果
instr函數不懂,instr(str,substr)
與instr(substr,str)
效果截然不同,但是利用select * from 表名where INSTR(CONCAT(字符串),CONCAT(表id))
實現了需求,mybatis中mapper如下:
<!--Action結果映射-->
<resultMap id="ActionMapper" type="Action">
<id column="act_id" property="actId"/>
<result column="act_name" property="actName"/>
<result column="machine" property="machine"/>
<result column="count_time" property="countTime"/>
<result column="count_class_id" property="countClassId"/>
<result column="strength_id" property="strengthId"/>
</resultMap>
<select id="getAction" resultMap="ActionMapper">
SELECT * FROM action WHERE INSTR(CONCAT(#{xx}),CONCAT(act_id));
</select>
<!--CoursePlan結果映射-->
<resultMap id="CoursePlanMapper" type="CoursePlan">
<id column="id" property="id"/>
<result column="plan_name" property="planName"/>
<result column="plan_class_id" property="planClassId"/>
<collection column="act_id" property="action" select="getAction"/>
</resultMap>
<insert id="add" parameterType="CoursePlan" >
insert into course_plan (plan_name,plan_class_id,act_id)
-- CONCAT_WS進行字符串拼接,以,為分隔符
values (#{planName},#{planClassId},CONCAT_WS(',',<foreach collection="action" item="actid" open="" close="" separator=",">#{actid.actId}</foreach>))
</insert>
<select id="getone" parameterType="_int" resultMap="CoursePlanMapper">
select * from course_plan where id= #{id}
</select>
<select id="list" resultMap="CoursePlanMapper">
select * from course_plan
</select>
</mapper>
更新:
上述語句出現了bug,本來相查詢id為17的值,但是順帶着7也出來了
解決方法:
SELECT * FROM action WHERE INSTR(CONCAT(',',17,','),CONCAT(',',act_id,','))
方法來源於該片博客:mysql使用instr達到in(字符串)的效果
意外發現
SELECT * FROM action WHERE INSTR(CONCAT(act_id),CONCAT(17));
將id字段和字符串互換位置后,這個問題好像 解決了
但是在這種情況下
查詢出現問題!!!所以行不通
查詢INSTR()
的用法,有所明悟:
INSTR(STR,SUBSTR) 在一個字符串(STR)中搜索指定的字符(SUBSTR),返回發現指定的字符的位置(INDEX);
STR 被搜索的字符串
SUBSTR 希望搜索的字符串
在字符串STR里面,字符串SUBSTR出現的第一個位置(INDEX),INDEX是從1開始計算,如果沒有找到就直接返回0,沒有返回負數的情況。