第一次写博客,可能描述方面还不够好,希望大家多多指教。
该需求中涉及到四个表:用户表、标签表、用户标签中间表、企业标签中间表。下面给大家附上表结构:
用户表:
标签表:
用户标签中间表:
其中isdeletedefault字段中:0表示是用户手动添加,1表示用户删除的默认标签2表示用户删除的企业自带的标签
企业标签中间表:
下面查看表机构
该需求就是,通过文章设置标签(及获得标签数组),给设置标签的用户,发送推送消息。
即:通过标签数组id如:1,2,3查询出设置该标签的所有用户列表。
思路分析:通过分析几种标签来源,来获取所有用户列表。经过分析,用户能够收到订阅的文章,主要通过三种方式。
第一种即:用户自己设置标签。第二种即:系统的默认标签(删除了系统默认标签的除外)。第三种即:企业设置标签(删除了企业标签的用户除外)。通过分析三种方式,获取每种方式下的所有用户列表,然后通过union关键字,将三个表连接起来去重即可。
第一种sql:
SELECT c.*
FROM t_user_tag t
LEFT JOIN cust c ON c.custid = t.userid
WHERE c.states = 1 AND
(
( t.tag_id = '3' AND isdeletedefault = 0 ) OR ( t.tag_id = '11' AND isdeletedefault = 0)
)
第二种sql:
SELECT c.*
FROM cust c
LEFT JOIN (
SELECT
t.userid
FROM
t_user_tag t
LEFT JOIN cust ct ON ct.custid = t.userid
WHERE
(
t.isdeletedefault = 1
AND t.tag_id = '3'
)
OR (
t.isdeletedefault = 1
AND t.tag_id = '11'
)
GROUP BY
t.userid
HAVING
COUNT (t.userid) = '2'
) del ON del.userid = c.custid
WHERE c.states = 1 AND del.userid IS NULL
or 括号内的内容,是默认标签数组id和将要设置的标签数组id的相交内容。如下表:
如果只是设置了一个标签11,则需要获取用户id为411,422,410的用户列表。
如果设置了标签3,11则需要获取用户id为410,412的用户列表。所以用了having关键字。
下面是java代码块:
String labels[] = label.split(",");//要设置的标签数组
List<String> la =new ArrayList<>(); //系统默认跟label的交集
List<Map<String, Object>> list = new ArrayList();//查询出系统默认的标签列表
for (int i=0; i<list.size(); i++) {
for (int j=0; j<labels.length; j++) {
if(list.get(i).get("tag_id").toString().equals(labels[j])) {
la.add(labels[j]);
}
}
}
//第二种情况的筛选条件---针对上面的那个表
if (la.size() == 0) {
remainUser.append(" ( 1=2) ");
} else if (la.size() ==1){
remainUser.append(" (t.isdeletedefault=1 and t.tag_id='"+la.get(0)+"' ) ");
} else {
for (int i = 0; i<la.size(); i++) {
remainUser.append(" (t.isdeletedefault=1 and t.tag_id='"+la.get(i)+"' ) ");
if (i<la.size()-1) {
remainUser.append(" or ");
}
}
remainUser.append(" group by t.userid having count(t.userid) ='"+la.size()+"' ");
}
第三种sql:同上
涉及知识点总结:
1.union关键字的使用
2.having关键字的使用
3.两个逗号相隔的字符串交集。通过两个for循环
4.sql语句中替换not in:即左连接子查询,然后查询条件设置为null。例子如下:
a.用not in
SELECT c.*
from cust c
where c.custid not in (
select t.userid
from t_user_tag t
LEFT JOIN cust ct on ct.custid =t.userid
where t.isdeletedefault=1
)
b.不用not in
SELECT c.*
from cust c
left join (
select t.*
from t_user_tag t
LEFT JOIN cust ct on ct.custid =t.userid
where t.isdeletedefault=1
) del on del.userid =c.custid
where del.user_tagid is null