mysql queries the contents of fields separated by commas
find_in_set function
background
When using mysql, it is possible that a field represents a collection. It is not worthwhile to separate this collection into a table. At this time, when we store, we can choose to separate the data with commas (only English commas can be used) , as shown in the figure:
How to check when doing a query?
single condition query
If a data is given as a query condition to determine whether the field exists, how should it be checked?
SELECT * FROM student where find_in_set('唱歌', sign) > 0;
It is easy to use the find_in_set() function to query the data containing the 'singing' attribute in the sign field instead of using like.
Multi-condition query for mybatis
1. Query with multiple conditions, for example: if it is suitable for both singing and dancing, you can write like this:
<if test="sign != null and sign != ''">
<foreach item="item" index="index" collection="sign.split(',')">
AND find_in_set(#{
item} , sign) > 0
</foreach>
</if>
2. To query multiple conditions, for example: if it is suitable for singing or dancing, you can write it like this:
<if test="list!= null and list != ''">
(
<trim prefixOverrides="AND|OR">
<foreach collection="list" item="item">
OR find_in_set(#{
item} , sign) > 0
</foreach>
</trim>
)
</if>
Aggregation query total count
How to calculate the total?
SELECT sum(LENGTH(sign) - LENGTH(REPLACE(sign,',','')) + 1) count FROM student;
Note: The length of the original field content - the length of the content after removing the comma = how many commas there are in the field; however, the last digit is without a comma, so +1 is required.
Query the list of distinct
There is no better way. We can only check the field of distinct sign first, and then use the program to judge one by one. . .
Does the find_in_set() function take the index?
Let's take a look at the execution plan (here the sign field is set as an index)
locate function
A field is separated by a comma. When querying, the input parameter is often a single or a collection (single use like or find_in_set), and the following methods can be used for the list:
select count(*) from engine_temp_variable where del_flag =0 and
<if test="list != null ">
(
<trim prefixOverrides="AND|OR">
<foreach collection="list" item="id">
or (locate(concat(#{
id},','),variableFieldIds) > 0 )
</foreach>
</trim>
)
</if>
Extension:
1. locate(substr,str): Returns the position str where the substring appears for the first time in the string substr, and returns 0 if it does not appear.
2. concat(str1, str2,…): concatenate multiple strings into one, if any parameter is null, the return value is null.
Reference link: find_in_set() function