zoukankan      html  css  js  c++  java
  • SQL练习题之子查询

    题目是 create table salesproduct (sid int,pid int)

    要求:查出pid中包含1,2,(3或4)的sid

    方法一使用独立子查询:

    View Code
    select 
    sid
    from salesproduct
    where
    pid
    =1
    and
    sid
    in(
    select sid from salesproduct where pid=2 )
    and
    (
    sid
    in
    (
    select sid from salesproduct where pid=3)
    or sid in
    (
    select sid from salesproduct where pid=4)
    )

    方法二:使用关联子查询

    select 
    sid
    from salesproduct a
    where pid=1
    and exists
    (
    select 1 from salesproduct b where b.pid=2
    and b.sid=a.sid)
    and exists
    (
    select 1 from salesproduct c where c.pid in (3,4)
    and c.sid=a.sid)

    方法三:使用表自连接

    select 
    distinct a.sid
    from
    SalesProduct a
    join salesproduct b
    on a.sid=b.sid
    join salesproduct c
    on b.sid=c.sid
    where
    a.pid
    =1 and b.pid=2 and c.pid in(3,4)

    方法四:类似数据透视

     
    select
    sid
    from
    (
    select sid,
    max(case when pid='1' then '1' end) as p1,
    max(case when pid='2' then '2' end) as p2,
    max(case when pid='3' then '3' end) as p3,
    max(case when pid='4' then '4' end) as p4
    from
    dbo.SalesProduct
    group by sid
    )
    as t
    where t.p1='1' and t.p2='2' and (p3='3' or p4='4')

     想一想,如果得到

    1 1,2,3,4

    2 1,2

    3 1,2,3

    4 1,2,4

    这样的结果呢?字符串的连接,可以使用coalesce结合透视完成.

    select *
    from
    (
    select sid,
    coalesce(max(case when pid='1' then '1' end),'')+
    coalesce(','+max(case when pid='2' then '2' end),'') +
    coalesce(','+max(case when pid='3' then '3' end),'')+
    coalesce(','+max(case when pid='4' then '4' end),'') as pidlist
    from
    dbo.SalesProduct
    group by sid
    )
    as t
    where pidlist in ('1,2,3,4','1,2,3','1,2,4')

    select
    sid,
    convert(varchar,coalesce([1],''))+
    convert(varchar,coalesce([2],''))+
    convert(varchar,coalesce([3],''))+
    convert(varchar,coalesce([4],'')) as pidlist
    from SalesProduct
    pivot
    (
    max(pid) for pid in ([1],[2],[3],[4])
    )
    as x

    第八章文中提到了字符串串联聚合的专用解决方案,使用for xml path('')技术,代码如下:

    select
    sid,
    stuff((select ','+ convert(varchar,pid)
    from dbo.SalesProduct as b
    where b.sid=a.sid
    order by pid
    for xml path('')),1,1,'') as [pidlist]
    from SalesProduct as a
    group by sid

     使用子查询的时候要注意一个陷阱,就是名称解析是从内部嵌套到外层的,如果你在嵌套层中select的列名不存在于嵌套查询的表中,而存在外表的时候,也不会报错,只是可能不是你要的结果.所以要注意.最好使用表别名.(inside sql server 2008)

    题目2 :生成数字辅助表

    一般直接用循环了,可是会产生很多的日志记录,所以速度会很慢.inside sql server 2008上介绍的方法,使用折半批量插入,利用到了sql本身集合操作的特点,还有一种常用的方法就是使用小的辅助表如果(0-9)的小表使用笛卡尔积的方法来插入.效果会更好.

      

     

  • 相关阅读:
    算法导论————KMP
    KMP算法
    几个很好的OJ网站
    查找(二分、hash、桶)
    动态规划
    贪心(未完待续)
    搜索的题
    codeVS 1031 质数环
    《将博客搬至CSDN》
    HDU1717小数化分数2
  • 原文地址:https://www.cnblogs.com/huaxiaoyao/p/2128535.html
Copyright © 2011-2022 走看看