表A:商店信息
ANO ANAME WQTY CITY
101 韶山书店 15 长沙
204 前门商店 89 北京
256 东风商场 501 北京
345 铁道商店 76 长沙
620 武汉商场 413 武汉表B:商品信息
BNO BNAME PRICE
1 毛笔 21
2 羽毛球 4
3 收音机 325
4 书包 242表AB:商店-商品对应关系
ANO BNO QTY
101 1 105
101 2 42
101 3 25
101 4 104
204 3 61
256 1 241
256 2 91
345 1 141
345 2 18
345 4 74
620 4 125现在要找出至少供应代号为256的商店所供应的全部商品的商店代号ANO,只涉及到表AB。这个SQL语句该怎么写?具体说,我已经知道关系表达式是:
π ano, bno (AB) ÷ π bno (σ ano = 256 (AB));我的问题是:如何把这里的除法运算转化为SQL语句呢?

解决方案 »

  1.   

    上面表的显示有点问题,我用逗号分隔重发一下:表A:商店信息
    ANO, ANAME, WQTY, CITY
    101, 韶山书店, 15, 长沙
    204, 前门商店, 89, 北京
    256, 东风商场, 501, 北京
    345, 铁道商店, 76, 长沙
    620, 武汉商场, 413, 武汉表B:商品信息
    BNO, BNAME, PRICE
    1, 毛笔, 21
    2, 羽毛球, 4
    3, 收音机, 325
    4, 书包, 242表AB:商店-商品对应关系
    ANO, BNO, QTY
    101, 1, 105
    101, 2, 42
    101, 3, 25
    101, 4, 104
    204, 3, 61
    256, 1, 241
    256, 2, 91
    345, 1, 141
    345, 2, 18
    345, 4, 74
    620, 4, 125谢谢大家!
      

  2.   

    现在要找出至少供应代号为256的商店所供应的全部商品的商店代号ANO,只涉及到表AB。这个SQL语句该怎么写?具体说,我已经知道关系表达式是:
    π ano, bno (AB) ÷ π bno (σ ano = 256 (AB));==================================不是很明白哦,能否把想要的结果贴出来?
      

  3.   

    不明白什么要用除法?是否是下面的意思:select * 
      from AB
     where AB.ANO <> 256
       and AB.BNO in
           (select AB.BNO
             from AB
            where AB.ANO = 256);====================result=========================
           ANO        BNO        QTY
    ---------- ---------- ----------
           345          1        141
           101          1        105
           345          2         18
           101          2         42
      

  4.   

    楼上的那段SQL没有注意到题目的一个要求是“256商店所提供的‘所有’商品”,所以它实际上把“256商店所供应的‘任意一个’商品”的商店都检索出来了。虽然结果是一致的,但是,我们观察一下AB表,如果把条件256换成101就能看出问题了。正是因为检索的要求是“所有”而不是“任意一个”,所以要用到除法,可是我手头的几本讲述关系代数的书都没有介绍除法在SQL语句里的实现,很奇怪。我应该把我的问题描述清楚了吧。大家帮帮忙哦!不甚感激!
      

  5.   

    你说吧,如果是101,sql语句产生结果是什么?是不是我下面的结果?还有可能是我愚昧,你为什么要用除法? 除法在这里有什么用?我还是有点不怎么明白 ...===========================sql========================================select * 
      from AB
     where AB.ANO <> 101
       and AB.BNO in
           (select AB.BNO
             from AB
            where AB.ANO = 101);
    ==========================result======================================
           ANO        BNO        QTY
    ---------- ---------- ----------
           345          1        141
           256          1        241
           345          2         18
           256          2         91
           204          3         61
           620          4        125
           345          4         747 rows selected
      

  6.   

    明白你的意思了,我测试成功的,你试试看~~~1:如果256的情况:---------------------sql-------------------------------    select *
          from AB AB_4
         where exists (select yy.ANO
                  from (select AB_1.ANO, count(*) as count_B1
                          from AB AB_1,
                               (select AB_2.ANO, AB_2.BNO
                                  from AB AB_2
                                 where AB_2.ANO = 256) zz
                         where AB_1.ANO <> zz.ANO
                           and AB_1.BNO = zz.BNO
                         group by AB_1.ANO) yy,
                       (select count(*) as count_B2
                          from AB AB_3
                         where AB_3.ANO = 256) rr
                 where count_B1 >= rr.count_B2
                   and yy.ANO = AB_4.ANO);
                
    =====================result================================
           ANO        BNO        QTY
    ---------- ---------- ----------
           101          4        104
           101          3         25
           101          2         42
           101          1        105
           345          4         74
           345          2         18
           345          1        1417 rows selected2:如果345的情况:---------------------sql-------------------------------    select *
          from AB AB_4
         where exists (select yy.ANO
                  from (select AB_1.ANO, count(*) as count_B1
                          from AB AB_1,
                               (select AB_2.ANO, AB_2.BNO
                                  from AB AB_2
                                 where AB_2.ANO = 345) zz
                         where AB_1.ANO <> zz.ANO
                           and AB_1.BNO = zz.BNO
                         group by AB_1.ANO) yy,
                       (select count(*) as count_B2
                          from AB AB_3
                         where AB_3.ANO = 345) rr
                 where count_B1 >= rr.count_B2
                   and yy.ANO = AB_4.ANO);
                
    =====================result================================
           ANO        BNO        QTY
    ---------- ---------- ----------
           101          4        104
           101          3         25
           101          2         42
           101          1        105~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    结果应该是满足LZ需求了, 你可以看看~~~
      

  7.   

    楼上辛苦啦,够哥们儿!XD~不过还是有问题:你看,256出售的商品有是1和2,同时出售1和2的商店还有101和345,所以如果是正确的语句,应该是检索出101、256和345这三个结果的。我听另外一个人说,关系代数的除法在SQL中的实现要用到NOT EXISTS,但他也写不出来。我手头的基本蛮经典的数据库教材和习题(包括萨王的《概论》还有清华出版的习题集),都回避了这个问题。我觉得真的很奇怪呢,明明这里面的逻辑那么简单,为什么SQL语句就那么难写呢?-_-'''
      

  8.   

    哈哈,我还以为你不要检索条件(256)中的数据了。。把AB_1.ANO <> zz.ANO去掉就可以了如果是256的情况:============================sql==============================    select *
          from AB AB_4
         where exists (select yy.ANO
                  from (select AB_1.ANO, count(*) as count_B1
                          from AB AB_1,
                               (select AB_2.ANO, AB_2.BNO
                                  from AB AB_2
                                 where AB_2.ANO = 256) zz
                         where AB_1.BNO = zz.BNO
                         group by AB_1.ANO) yy,
                       (select count(*) as count_B2
                          from AB AB_3
                         where AB_3.ANO = 256) rr
                 where count_B1 >= rr.count_B2
                   and yy.ANO = AB_4.ANO);============================result===========================       ANO        BNO        QTY
    ---------- ---------- ----------
           101          4        104
           101          3         25
           101          2         42
           101          1        105
           256          2         91
           256          1        241
           345          4         74
           345          2         18
           345          1        1419 rows selected
    如果是345情况的话:============================sql==============================    select *
          from AB AB_4
         where exists (select yy.ANO
                  from (select AB_1.ANO, count(*) as count_B1
                          from AB AB_1,
                               (select AB_2.ANO, AB_2.BNO
                                  from AB AB_2
                                 where AB_2.ANO = 345) zz
                         where AB_1.BNO = zz.BNO
                         group by AB_1.ANO) yy,
                       (select count(*) as count_B2
                          from AB AB_3
                         where AB_3.ANO = 345) rr
                 where count_B1 >= rr.count_B2
                   and yy.ANO = AB_4.ANO);============================result===========================
           ANO        BNO        QTY
    ---------- ---------- ----------
           101          4        104
           101          3         25
           101          2         42
           101          1        105
           345          4         74
           345          2         18
           345          1        1417 rows selected
      

  9.   

    NOT EXISTS 我试了结果出不来 ...可能是我能力有限,只能用上面的方法写出来,等待高手的回复 ...好像月亮和匆匆过客等高手他们这段时间都去“闭关修炼”去了,嘿嘿,高手总是隐藏在最深处 ... 
      

  10.   

    Try:SELECT ANO
      FROM AB T1,
           (SELECT BNO, COUNT(*) OVER() CNT FROM AB T1 WHERE ANO = '256') T2
     WHERE T1.BNO = T2.BNO
     GROUP BY ANO, CNT
    HAVING COUNT(ANO) = CNT
      

  11.   

    select * from AB where ANO in (
    select distinct ANO from AB
    where  BNO in 
    (select BNO from AB
    where ANO= '345' )
    and FSFURIKAEID <> '345')用这个方法是可行的
    exists还有待研究的
      

  12.   

    谢谢mantisXF啊,你的代码我测试过了,虽然看起来超复杂,但真的是成功的,哈哈~我昨天在希赛网上也找到了个高手,他给我的版本是这样的(嵌套了两层NOT EXISTS),大家一起来研究下吧:
    SELECT C.ANO
      FROM AB as C
     WHERE NOT EXISTS (SELECT *
              FROM AB as D
             WHERE D.ANO = 101
               AND NOT EXISTS (SELECT *
                      FROM AB as E
                     WHERE C.ANO = E.ANO
                       AND D.BNO = E.BNO));关键是NOT EXISTS跟关系代数的除法究竟是怎样的对应关系?谁能分析一下?我们要做到“知其然,知其所以然”
      

  13.   

    SELECT   C.ANO
        FROM   AB   as   C
      WHERE   NOT   EXISTS   (SELECT   *
                        FROM   AB   as   D
                      WHERE   D.ANO   =   101 (带入下面的循环)
                          AND   NOT   EXISTS   (SELECT   *
                                        FROM   AB   as   E
                                      WHERE   C.ANO   =   E.ANO
                                          AND   D.BNO   =   E.BNO) ()); 必须满足上面红色字体的条件才会被选出,遍历所有column,然后有一个bno满足所有的( C.ANO   =   E.ANO AND   D.BNO   =   E.BNO)这里的D是满足条件D.ano = 101的