今天做个筛选查询搞了一下午没有搞好,有没有大佬帮帮我,就一个筛选

简单描述下要筛选的东西
表AB
id   product       create_user       表A_id   status    
1    螺丝           小红               1       新创建
2    螺丝           小明               1       生产中 
3    螺帽           小红               1       已完成
                                      1       已交付
                                      2       生产中
                                      3       生产中
上述就是表里的数据内容

页面上就呈现
产品    状态
 螺丝   已交付
 螺帽   生产中

 同一种产品可以有多个人创建,但状态的话取生产的最新进度的状态,所以螺丝在表B取已交付,螺帽取生产中,现在我要状态筛选生产中的哪些产品,我该怎么筛选,我下午的方式是从表B中取状态为生产中的,能够查到1,2,3但是1有后面两种状态,所以我就将1unset掉了,只剩下2,3,然后去表A中拿2,3去查得到螺丝和螺帽,但螺丝其实状态已经是已交付了,是由于1,2这个两个id之间产生了影响。


 所以我应该怎么写查询,搞的头都大了
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
最佳答案

感谢各位大佬提供的方案,我放弃了,从现有的来说真的搞不定,只能选择加表

2年前 评论
小猪蹄子 2年前
讨论数量: 28
leo

SQL 不好写的时候为什么不考虑考虑是不是表结构设计的问题?

2年前 评论
study_laraveler (楼主) 2年前
Jappar 2年前

B表加个更新时间 ,取更新时间最大的应该没问题吧?

我写不好 SQL 的时候就用数组遍历来处理

2年前 评论
study_laraveler (楼主) 2年前
aab

看样子有两种方法,如果B表有主键的话可以写成这样 如果Mysql的版本低于 8.0 可以使用 select * from a join (select * from b join (select max(b.id) last_id from a join b where a.id = b.a_id group by a_id) t on b.id = t.last_id) t1 on t1.a_id = a.id;

高于 8.0 可以用这个 select * from (select a.*, b.status, rank() over (partition by a.id order by b.id desc) last_status from a join b on b.a_id = a.id) t where t.last_status = 1;

2年前 评论
study_laraveler (楼主) 2年前
MArtian 2年前
study_laraveler (楼主) 2年前
leo

SQL 不好写的时候为什么不考虑考虑是不是表结构设计的问题?

2年前 评论
study_laraveler (楼主) 2年前
Jappar 2年前
Junwind

最好是直接查,php在做处理

2年前 评论

要不再加一个表? id value 1 生产中 2 已完成

2年前 评论
study_laraveler (楼主) 2年前
tsingyan (作者) 2年前

我的想法是表A表B,都加一个字段,,叫产品ID(相同的产品ID一样)
表A groupBy 产品ID 然后就可以关联出来了

2年前 评论

状态可以为数字,数字越大工序状态越靠后,通过状态排序

2年前 评论

如果能加字段的话,b表加一个值为数字的状态字段,随着工序增大,然后通过group表A_id然后max(status)去查询,如果加不了字段就查出来程序去处理

2年前 评论

select A.product,group_concat(distinct B.status) as status from A join B on A.id=B.A_id group by A.product 拿出来后再交给后端遍历处理搜集到的status

2年前 评论
SELECT * FROM A WHERE 
id IN (SELECT id FROM B  WHERE  `status`  IN ('生产中')) 
AND id NOT IN(SELECT id FROM B  WHERE  `status` NOT IN ('已完成','已交付'))  

这样可以查不

2年前 评论
study_laraveler (楼主) 2年前
select *,sum(if(end_num>0,1,0)) as sum_num from (SELECT
    `id`,`product`,`create_user`,
    (SELECT
            count(1)
        FROM
            `B`
        WHERE
            `A`.`id` = `B`.`A_id`
        AND `status` = '生产中') as `todo_num`,
        (SELECT
            count(1)
        FROM
            `B`
        WHERE
            `A`.`id` = `B`.`A_id`
        AND `status` in ('已完成',"已交付")) as `end_num`
FROM
    `A`) as A_temporary
group By product
HAVING sum_num = 0
AND todo_num > 0
2年前 评论

感谢各位大佬提供的方案,我放弃了,从现有的来说真的搞不定,只能选择加表

2年前 评论
小猪蹄子 2年前

status状态 改为数字 数字越大表示状态越靠后,查询时取数字最大那条状态就行了

2年前 评论

可以用trigger的吧,状态改变的时候去自动维护一个表,查询的时候也查询这个表。

2年前 评论

建表的真是个不可多得的人才

2年前 评论

把 B 表改成有则更新,没有才添加。

file 这样应该改动不会太大吧

2年前 评论

你给B表加一个主键然后max id不就可以了,你要是说状态的诞生就是无序没有阶段性的,这不胡扯么,如果是导入数据就该在数据导入那里排序好,你硬说无序的话,那你就新建一个变量或者是文件,维护每个状态拥有的状态数据条数,查询时,left join having count等于具体具体数量就好了

$number = 数量;
SELECT a.id, a.name, COUNT(b.id) AS total FROM a LEFT JOIN b ON a.id = b.id GROUP BY b.id HAVING total = $number;

你要是再说状态有可能跳着来还少数据,上面已经说的那个无序够不合理了,还来就别搞咯

2年前 评论
nff93

我更倾向于在A表加一个当前状态的字段

2年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!