SQL:存储过程中创建动态视图

需求:新建一存储过程 proc5,实现查询
购买过指定书目ID的用户
同时
该用户购买过的购买次数最多的前3名书目名称及购买次数

解决过程:

  1. 创建存储过程,为指定ID创建变量
CREATE PROCEDURE proc5 @book_id int
  1. 通过@book_id查询购买过指定书目ID的用户userId
select distinct(userID) 
from orderBook ,orderInfo 
where orderBook.orderID=orderInfo.orderID 
      and bookID=@book_id
  1. 通过步骤2的子查询,就可以查询这些用户买的书籍以及购买的次数
select userID ,bookID ,count(orderbook.orderID) as buy_times
from orderBook ,orderInfo 
where orderBook.orderID=orderInfo.orderID 
  and userID in (select  distinct(userID) 
                 from orderBook ,orderInfo 
			     where orderBook.orderID=orderInfo.orderID 
					   and bookID=@book_id
group by userID,bookID 
order by buy_times desc

此时的查询结果很长,查询内容忽略
因为还要进一步的筛选:这些用户购买的书籍次数前三
在这里插入图片描述
此时的结果只有三个字段,而执行的sql语句却很长
解决办法:
通过创建临时视图,即使用完就删除,帮助进一步的筛选查询
注意:创建排序视图使用order by 是不正确的,因为视图只是对查询结果保存的一张表

CREATE VIEW v_result AS
---------------------------------------------
select userID ,bookID ,count(orderbook.orderID) as buy_times
from orderBook ,orderInfo 
where orderBook.orderID=orderInfo.orderID 
  and userID in (select  distinct(userID) 
                 from orderBook ,orderInfo 
			     where orderBook.orderID=orderInfo.orderID 
					   and bookID=@book_id
group by userID,bookID 

此时只需要考虑userId,bookId,buy_times这三个字段

select userId,bookId,buy_times 
from v_result
order by buy_times desc 
  1. 回到解题过程,此时需求是: 返回这些用户购买的书籍次数前三的书籍bookId
  2. 意思时返回:分组后返回同组数据的前三
    以下是参考:
    sql查询各科成绩前三名----详述过程,思路清晰不烧脑
    COUN函数的区别
select *
from v_result as v1
where 3>(select count(1) 
         from v_result as v2 
         where v1.userID=v2.userID 
             and v1.buy_times>v2.buy_times)
order by userID desc ,bookID desc
  1. 将结果写入存储过程,完成!
CREATE PROCEDURE proc5 @book_id int 
AS
---------------------------------------------
declare @sql_str varchar(max)=''
select @sql_str =
'CREATE VIEW v_result AS 
select userID ,bookID ,count(orderbook.orderID) as buy_times
from orderBook ,orderInfo 
where orderBook.orderID=orderInfo.orderID 
     and userID in (select  distinct(userID) 
                     from orderBook ,orderInfo 
                     where orderBook.orderID=orderInfo.orderID 
                      and bookID='+CONVERT(varchar,@book_id)+')
group by userID,bookID '
-------------------------------------------------------
--print(@sql_str)测试
--视图作为临时表需要使用完之后删除
if exists (select * from sys.objects where name = 'v_result')
      drop view v_result
exec(@sql_str)
----------------------------------------------------------
select *
from v_result as v1
where 3>(select count(1) 
         from v_result as v2 
         where v1.userID=v2.userID 
             and v1.buy_times>v2.buy_times)
order by userID desc ,bookID desc

问题一:在存储过程中使用CREATE VIEW会报错:
参考:
存储过程中创建动态视图
问题二:在创建动态视图时候一开始声明varchar(255)通过print()打印出来不能完整显示要exec()执行的字符串:
参考:
varchar长度问题

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值