zoukankan      html  css  js  c++  java
  • 用 SQLServer 2005 PIVOT 函数 巧解题

    补充:巧不巧,大家看下就知道了,如果觉得不巧,再拍砖也不迟,^_^

    背景

    SQLServer 2005 联机从书:

    PIVOT:通过将表达式某一列中的唯一值转换为输出中的多个列来旋转表值表达式,并在必要时对最终输出中所需的任何其余列值执行聚合。

    UNPIVOT PIVOT 执行相反的操作,将表值表达式的列转换为列值。


    来看下题目
    :
    How can I get a list of the stores that have bought both 'bussiness' and 'mod_cook' type books?

    In database pubs, use three table stores,sales and titles to implement this requestment.

    Now I want to get the result as below:

    stor_id stor_name                               

    ------- --------------------

    ...

    7896    Fricative Bookshop

    ...


    这是我进公司时SQL培训出的题.其中的pubsSQLServer的示例数据库.(SQLServer中添加pubs的代码见附件)

     

    Pubs示例库设计信息,没用过Pubs示例库的可以参考下

     

    查看 stores,sales and titles 关联后的表

    1with temp as
    2(
    3  SELECT dbo.stores.stor_id,dbo.stores.stor_name,dbo.titles.type,dbo.sales.qty
    4  FROM dbo.sales 
    5    INNER JOIN dbo.stores
    6      ON dbo.sales.stor_id=dbo.stores.stor_id
    7    INNER JOIN dbo.titles
    8      ON dbo.sales.title_id=dbo.titles.title_id
    9)

    //如果对temp进行查询,则结果为:

     

    一、常规的思路:

    利用子查询

    1select distinct stor_id,stor_name
    2from temp as t
    3where [type]= 'business' and exists
    4  (
    5    select * from temp where stor_id = t.stor_id and [type] = 'mod_cook'
    6  )

     

    这种方法容易理解,但是执行效率低,会出现多次扫描表!我们来看第二种思路(我的解法)

     

    二、利用PIVOT函数,来个行列转换:

             typebusinessmod_cook列值转换成表的字段,就可以直接用where business is not null and mod_cook is not null 直接筛取了

    详细过程:

    1.转置

    1SELECT stor_id,stor_name ,[business],[mod_cook]
    2FROM temp AS S
    3PIVOT
    4(
    5  SUM(qty)
    6  FOR [type] in([business],[mod_cook])
    7AS R
    8
    9

    结果:

     

    2.据条件筛:WHERE [business] IS NOT NULL AND [mod_cook] IS NOT NULL

    结果:

     

    应题目需要,修改后的代码完整如下:

     1SELECT stor_id,stor_name
     2FROM temp AS S
     3PIVOT
     4(
     5  SUM(qty)
     6  FOR [type] in([business],[mod_cook])
     7AS R
     8WHERE [business] IS NOT NULL AND [mod_cook] IS NOT NULL
     9
    10

     

    最终结果:

     

    这个种方法比较拗,但利用了PIVOT转置行列避免了多次扫描表,效率不错!

     

    也是新手,如果有不对的或是不合理的地方大家多拍砖!

    附:向数据库添加Pubs实例库的代码:https://files.cnblogs.com/FojamesChen/pubs.rar

  • 相关阅读:
    浅谈Eclipse中maven的搭建
    sdk的相关知识以及浅谈手机模拟自动化
    java开发环境搭建
    Python学习————反序列化器(复习)
    Python学习————序列化器(复习)
    Python学习————jwt
    Python学习————对称加密和非对称加密
    Python学习————drf(七)
    Python学习————集群和分布式
    Python学习————drf(六)
  • 原文地址:https://www.cnblogs.com/FoChen/p/1278545.html
Copyright © 2011-2022 走看看