sql编程——join,concat,except,union all的使用举例。

sql题目

现需要请向所有用户推荐其朋友收藏但是用户自己未收藏的商品,请从好友关系表(friendship_info)和收藏表(favor_info)中查询出应向哪位用户推荐哪些商品。

friendship_info

user1_id(用户1 id) user2_id(用户2 id)
101 1010
101 108
101 106

favor_info

user_id(用户id) sku_id(商品id) create_date(收藏日期)
101 3 2021-09-23
101 12 2021-09-23
101 6 2021-09-25

期望效果

user_id <string> (用户id) sku_id <string> (应向该用户推荐的商品id)
101 2
101 4
101 7
101 9
101 8
101 11
101 1

题目讨论

本题的思路分析是,首先找到朋友收藏的商品,然后将朋友的商品剔除掉包含自己收藏的商品

1. 使用union all合并,然后使用having 求countI()为1
1.将好友表与收藏表join,获取好友收藏商品
sql 复制代码
select
      fi.user1_id as user_id,
  sku_id
from
  friendship_info fi
  join favor_info fo on fi.user2_id = fo.user_id
group by
  fi.user1_id,
  sku_id
2.查询自己收藏的商品,合并所有商品与用户
sql 复制代码
UNION ALL
select
  user_id,
  sku_id
from
  favor_info
3.对行数进行筛选,使用having过滤出统计数为1的即为用户未曾收藏的商品。
sql 复制代码
select
  user_id,
  sku_id
from t1
group by
  user_id,
  sku_id
having
  count(*) = 1
4.最终SQL
sql 复制代码
select
  user_id,
  sku_id
from
  (
    select
      user_id,
      sku_id
    from
      (
        select
          fi.user1_id as user_id,
          sku_id
        from
          friendship_info fi
          join favor_info fo on fi.user2_id = fo.user_id
        group by
          fi.user1_id,
          sku_id
      ) t1
    UNION ALL
    select
      user_id,
      sku_id
    from
      favor_info
  ) t
group by
  user_id,
  sku_id
having
  count(*) = 1
2.使用concat()拼接后,再去重
1.收藏表关联原表
sql 复制代码
friendship_info t1 

JOIN favor_info t2

on t1.user2_id=t2.user_id
2.拼接用户-商品作为一个字段
sql 复制代码
concat(t1.user1_id,t2.sku_id)
3.将用户-商品不存在的自己收藏的进行过滤
sql 复制代码
where concat(t1.user1_id,t2.sku_id) not in (

    SELECT concat(user_id,sku_id)

    from favor_info

)
4.最终SQL
sql 复制代码
SELECT t1.user1_id user_id,t2.sku_id

from friendship_info t1 

JOIN favor_info t2

on t1.user2_id=t2.user_id

where concat(t1.user1_id,t2.sku_id) not in (

    SELECT concat(user_id,sku_id)

    from favor_info

)

group by t1.user1_id,t2.sku_id
3.使用join连接获取所有数据,然后根据关联信息过滤不需要的数据

使用join进行关联我认为是最符合码农习惯的。关联获取数据然后根据左关联右关联,将控制空值过滤,该方法主要是熟悉join后数据集的生成结果

1.好友表关联收藏表,获取好友id
sql 复制代码
from friendship_info fi

join favor_info fi1

on fi.user2_id = fi1.user_id 
2.再次关联收藏表,获取用户信息以及收藏商品信息
sql 复制代码
left join favor_info fi2

on fi.user1_id = fi2.user_id and fi1.sku_id = fi2.sku_id
3. 按照商品关联情况过滤, 对用户,好友商品进行去重。
sql 复制代码
select distinct user1_id user_id,

    fi1.sku_id sku_id

from t1

where fi2.sku_id is null;
4.最终SQL
sql 复制代码
select distinct user1_id user_id,

    fi1.sku_id sku_id

from friendship_info fi

join favor_info fi1

on fi.user2_id = fi1.user_id 

left join favor_info fi2

on fi.user1_id = fi2.user_id and fi1.sku_id = fi2.sku_id

where fi2.sku_id is null;
4.使用except关键字,剔除重复数据。

except关键字有去重复数据效果,最新的hive语法支持except关键字。

可以使用 where ... is not exists替代except

sql 复制代码
select
  friendship_info.user1_id as user_id,
  sku_id
from
  friendship_info
  join favor_info on friendship_info.user2_id = favor_info.user_id
except
select
  user_id,
  sku_id
from
  favor_info

本题最主要的还是要懂join后的结果集,才能做到对重复数据,无效数据去重。

相关推荐
SAP小崔说事儿4 小时前
在数据库中将字符串拆分成表单(SQL和HANA版本)
java·数据库·sql·sap·hana·字符串拆分·无锡sap
川贝枇杷膏cbppg4 小时前
asmcmd
数据库·oracle
MatrixOrigin5 小时前
在数据库里玩“平行宇宙”:MatrixOne Data Branch 让数据也拥有Git 的分支/合并/对比/回滚(含跨集群同步)
git·sql·数据分析
JIngJaneIL5 小时前
基于java+ vue助农电商系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
IndulgeCui5 小时前
基于CentOS7 DM8单机部署配置记录-20251216
数据库
surtr15 小时前
关系代数与关系型数据库
数据库·sql·数据库系统
学海_无涯_苦作舟5 小时前
MySQL面试题
数据库·mysql·面试
老邓计算机毕设6 小时前
SSM校内二手书籍交易系统的设计与实现an1k0(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面
数据库·ssm 框架·ssm 框架开发·ssm 校内二手书籍交易系统
天行健,君子而铎6 小时前
高性能、可控、多架构:教育行业数据库风险监测一体化解决方案
数据库·架构
Stella25216 小时前
实习日志|知识总结
linux·服务器·软件测试·数据库