技术开发 频道

关于一段SQL的探讨

    【IT168 MSSQL文档】四张表分别如下:
    (1)customers(cid,cname,city)
    (2)products(pid,pname,city,quantity,price)
    (3)agent(aid,aname,city,percent)
    (4)order(ordno,month,cid,aid,pid,qty,dollars)
   
   
    要求检索出被所有“BOSTON”城市的顾客所定购的产品号
   
    SELECT pid
    from products
    where not exists
    (select customers.cid
    from customers
    where customers.city = 'BOSTON' and not exists
    (select *
    from orders
    where orders.pid = products.pid
    and products.cid = customers.cid
    ));
    

    --------------------------------------------------------------------------------
    作者:lodge    时间:04-09-28 17:41
   
    很经典的一个例子, 最早应该是在C.J.DATE所著那本数据库名著上出现的吧
   
    这四张表用汉语来表现就是
    (1)顾客表(顾客ID,姓名,城市)
    (2)产品表(产品ID,名称,城市,数量,价格)
    (3)代理表(代理ID,名称,城市,份额)
    (4)定单表(定单编号,月份,顾客ID,代理ID,产品ID,数量,金额)
   
    对SQL文可做以下理解,
    因为要取的是产品编号, 所以,
    SELECT pid
    from products
    下面分析检索条件,
   
    被所有“BOSTON”城市的顾客所定购的产品号, 可以换一种方式说, 对该产品来说, 不存在住在“BOSTON”且, 没有定过该产品的顾客
    先来找, 住在“BOSTON”的顾客
    select customers.cid
    from customers
    where customers.city = 'BOSTON'
    如何知道某一顾客是否定过某一产品捏? 自然要去找定单表,
    select *
    from orders
    where orders.pid = 某产品ID
    and products.cid = 某顾客ID
    当记录存在是就表示该顾客定购过该产品, 反过来, 如果记录不存在则表示该顾客没有定过该产品
    和前一个检索连起来
    select customers.cid
    from customers
    where customers.city = 'BOSTON' and not exists
    (select *
    from orders
    where orders.pid = 某一产品ID
    and products.cid = customers.cid
    )
    就成了找出在'BOSTON' 而从未定购过某一产品的顾客的检索表达式, (这里EXISTS比较难理解, 为形象一些, 可以把它看成是个循环体中套用的函数, 用主查询的结果一条一条的执行子查询, 当子查询有记录返回时, 则为真否则为假), 如果找不到这样的顾客, 则说明所有'BOSTON'人都定购过这个产品,
    于是, 全部连起来, 就成了上面的样子。
0
相关文章