MySql中一次查询结果用作二次查询条件

Sql的截取关联查询

最近在写sql时,碰到了如下情况,
需求是通过一个账户的id去查询关联的该账户下的所有简历,其中地址字段要通过另一个表进行关联查询。地址字段存的是地址表中对应的编号。

例如210000,210100,210106 代表辽宁省沈阳市铁西区。

通过截取地址字段,分出3个字符串然后进行分别关联查询

语句如下:
输入图片说明
输入图片说明

插的图片,插代码块的格式我也有点迷
当数据库中该用户下只有一份简历的时候,这条语句是成立的,但如果有多条就会报错

[Err] 1242 - Subquery returns more than 1 row

子查询超过一行以上

原因在于查询条件,当有多份简历时,查询的简历id不唯一

WHERE prt.user_info_id=(
            SELECT pit._id
            FROM person_info_t pit
            WHERE pit.user_id=@pti_user_id)
) 

临时表数据中转 调用过程循环查询

创建一张表作为储存简历的id

drop table if exists tmp_table;  
create table tmp_table (                             -- 创建一张表作为本次储存数据的中转站  也可以用临时表来代替
id INT UNSIGNED NOT NULL auto_increment,             -- id自增
prt_id varchar(64),                                  -- 储存简历id
PRIMARY KEY (id)
); 
  • UNSIGNED 表示无符号
  • MYSQL中整型范围
类型大小范围(有符号)范围(无符号)用途
TINYINT1 字节(-128,127)(0,255)小整数值
SMALLINT2 字节(-32 768,32 767)(0,65 535)大整数值
MEDIUMINT3 字节(-8 388 608,8 388 607)(0,16 777 215)大整数值
INT或INTEGER4 字节(-8 388 608,8 388 607)(0,4 294 967 295)大整数值

从临时表中查找并将简历的id插入到表中,count结果用作循环次数限制

INSERT INTO tmp_table(prt_id) 
SELECT prt. _id FROM person_resume_t prt ,person_info_t pit 
WHERE prt.user_info_id = pit._id 
AND pit.user_id = "98444836924a4c67845da048a77e29d6";
SET @j=0;
SELECT COUNT(*) INTO @j FROM tmp_table;

创建查询过程,在这说下,sql循环是个坑,卡了我好长时间
- mysql 循环在存储过程中才受支持,存储过程外不能用
- mysql 循环在存储过程中才受支持,存储过程外不能用
- mysql 循环在存储过程中才受支持,存储过程外不能用

CREATE PROCEDURE selectPrtInfoByPrtId(IN j int)
BEGIN
DECLARE i INT;
                SET i=1;
                WHILE i<j+1  do
SELECT
prt._id,prt.production_pic_url,prt.video_url,prt.user_info_id,
prt.skill_tag,prt.sex,prt.phone_number,prt.head_pic_url,
prt.introduction,prt.`name`,prt.modify_time,prt.email,
prt.create_time,prt.birth,prt.address,prt.resume_name,
(select re.REGION_NAME 
from region re 
inner join person_resume_t prt 
on re.REGION_CODE = SUBSTRING_INDEX(prt.address,',',1) 
WHERE prt._id=(   -- 此处拿到简历id
            SELECT tt.prt_id 
            FROM tmp_table tt 
            WHERE tt.id = i)
)  
as province,
(select re.REGION_CODE 
from region re 
inner join person_resume_t prt 
on re.REGION_CODE = SUBSTRING_INDEX(prt.address,',',1) 
WHERE prt._id=(
            SELECT tt.prt_id 
            FROM tmp_table tt 
            WHERE tt.id = i)
) 
as province_id,
(select re.REGION_NAME 
from region re 
inner join person_resume_t prt 
on re.REGION_CODE = SUBSTRING_INDEX(SUBSTRING_INDEX(prt.address,',',2),',',-1) 
WHERE prt._id=(
            SELECT tt.prt_id 
            FROM tmp_table tt 
            WHERE tt.id = i)
) 
as city,
(select re.REGION_CODE 
from region re 
inner join person_resume_t prt 
on re.REGION_CODE = SUBSTRING_INDEX(SUBSTRING_INDEX(prt.address,',',2),',',-1) 
WHERE prt._id=(
            SELECT tt.prt_id 
            FROM tmp_table tt 
            WHERE tt.id = i)
) 
as city_id,
(select re.REGION_NAME 
from region re 
inner join person_resume_t prt 
on re.REGION_CODE = SUBSTRING_INDEX(prt.address,',',-1) 
WHERE prt._id=(
            SELECT tt.prt_id 
            FROM tmp_table tt 
            WHERE tt.id = i)
) 
as district,
(select re.REGION_CODE 
from region re 
inner join person_resume_t prt 
on re.REGION_CODE = SUBSTRING_INDEX(prt.address,',',-1) 
WHERE prt._id=(
            SELECT tt.prt_id 
            FROM tmp_table tt 
            WHERE tt.id = i)
) 
as district_id
FROM person_resume_t prt
WHERE prt._id=(SELECT tt.prt_id FROM tmp_table tt WHERE tt.id = i)
ORDER BY prt.create_time;

        SET i = i + 1;
        END WHILE;

 END

声明变量i,用作索引来查找临时表中的id,j为传入的限制循环次数,每次查询后返回查询结果,也可以在弄一个表来接收

执行一下

drop table if exists tmp_table;  
create table tmp_table (                            
id INT UNSIGNED NOT NULL auto_increment, 
prt_id varchar(64),
PRIMARY KEY (id)
); 
INSERT INTO tmp_table(prt_id) 
SELECT prt. _id FROM person_resume_t prt ,person_info_t pit 
WHERE prt.user_info_id = pit._id 
AND pit.user_id = "98444836924a4c67845da048a77e29d6";
SELECT COUNT(*) INTO @j FROM tmp_table;
SELECT @j;
CALL selectPrtInfoByPrtId(@j);

返回结果如下
输入图片说明
返回三条结果,总结一下:
- sql的循环离不开储存过程的支持,单独拿出来写并不好用
- 变量的作用域问题,尝试时全局变量的值很容易出现问题
- mysql中也没有控制台的概念,整个就是控制台,可以通过select的方式来查看值

MySQL 架构,缓存是由查询缓存(Query Cache)组件来实现的。当启用了查询缓存功能时,MySQL 会将查询结果存储在缓存,以便在后续相同的查询被执行时能够直接从缓存获取结果,而无需执行实际的查询操作。 在执行查询之前,MySQL 会检查查询语句是否存在于查询缓存。这个检查过程包括以下几个步骤: 1. 查询语句的文本会被用作一个哈希值的计算。 2. 这个哈希值会被用来检索查询缓存的一个缓存条目。 3. 如果存在对应的缓存条目,MySQL 会检查查询语句是否与缓存条目完全匹配(包括查询语句的文本、查询参数、数据库名等)。 4. 如果查询语句与缓存条目完全匹配,MySQL 将直接从缓存获取结果,并将其返回给用户,而不会执行实际的查询操作。 需要注意的是,查询缓存是基于查询语句的完全匹配来进行的。即使查询语句的某个表发生了变化,或者缓存的数据被修改,只要查询语句完全匹配,MySQL 仍然会返回缓存的结果。因此,在使用查询缓存时需要特别注意缓存的更新策略,以避免返回过时或不正确的结果。 值得一提的是,自 MySQL 8.0.3 版本开始,查询缓存功能已被废弃,并在后续版本被移除。这是因为查询缓存在高并发、大数据量情况下效果不佳,容易引起性能问题。因此,建议在使用较新版本的 MySQL 时,不再依赖查询缓存功能。替代的解决方案可以是使用更高效的缓存系统,如 Memcached 或 Redis 等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值