mysql行转列,查询时字符串判断一个解决方案

在一次开发时候想把一条sql把人员的基本信息和其他属性全部查出来,但是其他属性查出来是一个list,所以使用用行转列来解决

查出来的基本属性如下图


SELECT
    hi.ctyName,
    hi.builderName,
    hi.unitName,
    hi.NAME AS houseName,
    p.NAME,
    p.mobile,
    p.id,
    p.idNbr,
    p.householdPace,
    p.householdPaceDetail,
    n.NAME AS nation 
FROM
    person_info pi
    LEFT JOIN house_info hi ON pi.houseId = hi.id
    LEFT JOIN person p ON pi.personId = p.id
    LEFT JOIN nation n ON n.CODE = p.nation 
WHERE
    pi.STATUS = 1 
    AND (
        YEAR (
        NOW())- SUBSTRING( p.idNbr, 7, 4 )) >= 5 
    AND (
        YEAR (
        NOW())- SUBSTRING( p.idNbr, 7, 4 )) <= 50 
ORDER BY
    hi.id
 

其他属性

SELECT * from person_attr_val where personId = 126179

 

 然后想把这个两个sql合并成一个,但是一个是一条数据,一个结果是个list,所以用mysql中的行转列解决

SELECT
        hi.ctyName,
        hi.builderName as buildName ,
        hi.unitName,
        hi.NAME AS houseName,
        pt.name as personType,
        p.name,
        p.mobile,
        p.id,
        p.idNbr,
        p.householdPace,
        p.householdPaceDetail,
        n.name AS nation,
                IF(INSTR(p.tag,'26') >0 ,'是','否') as tag,
                pa.*
        FROM
        person_info pi
        LEFT JOIN house_info hi ON pi.houseId = hi.id
        LEFT JOIN person p ON pi.personId = p.id
        LEFT JOIN nation n ON n.CODE = p.nation
        LEFT JOIN person_type pt ON pt.code = pi.registrationType
                LEFT JOIN ((SELECT personId ,
Max(case WHEN  attrId = '32' THEN  `value` ELSE NULL END) as "学历", 
Max(case WHEN  attrId = '13' THEN  `value` ELSE NULL END) as "政治面貌",
Max(case WHEN  attrId = '42' THEN  `value` ELSE NULL END) as "从事职业",
Max(case WHEN  attrId = '43' THEN  `value` ELSE NULL END) as "从事单位"        
from person_attr_val GROUP BY personId) as pa) on pa.personId=pi.personId
                
  WHERE
        pi.status = 1

现在完美解决了,但是又遇到另一个问题,就是我们有一个人员标签字段,可以有多个属性用“,”来分割开,我要判断每个人是否存在这个属性,开始我用CONTAINS这个函数,但是报 Invalid GIS data provided to function mbrcontains错误,结果是InnoDB不支持这个函数,后来去mysql官方查询发现了INSTR函数可以判断,就是这条IF(INSTR(p.tag,'26') >0 ,'是','否') as tag,当存在时,就会返回匹配到的位置,此时所以问题全部解决

MySQL中,判断两个由逗号分隔的字符串是否有交集,通常需要将它们转换成数组或者使用FIND_IN_SET函数。但是,MySQL本身并不直接支持数组操作。我们可以采取以下步骤: 1. **创建临表或用户变量**:首先,你需要把字符串拆分成数组(如果数据库版本支持JSON的话,可以用JSON_TABLE)或者存储过程。 ```sql CREATE TEMPORARY TABLE IF NOT EXISTS str_table (str_column VARCHAR(255) DEFAULT ''); ``` 2. **插入字符串并拆分**:然后,你可以分别插入这两个字符串,并使用SUBSTRING_INDEX函数对每个进行拆分。 ```sql INSERT INTO str_table (str_column) VALUES ('str1, val1, val2'); INSERT INTO str_table (str_column) VALUES ('str2, val3, val4'); ``` 3. **使用FIND_IN_SET**:对于每个子串,检查它是否存在于另一个字符串的集合中。可以使用FIND_IN_SET函数,如果找到则表示有交集。 ```sql SELECT FIND_IN_SET('val1', str_column) > 0 AS has_intersection FROM str_table WHERE str_column = 'str1, val1, val2'; ``` 4. **结果判断**:最后,通过比较查询结果判断是否有交集。如果有一个查询返回非零,则说明有交集。 如果你不希望创建临表,也可以在一个存储过程中完成整个逻辑。 注意:这种方法效率不是很高,特别是对于大数据量的情况。如果性能是一个关键点,你可能需要考虑其他的解决方案,比如使用JOIN操作结合其他数据库特性,或者在应用程序层面处理这个问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值