首页 > SQL问个基础例子,书上的,我怎么看都看不懂..谁帮我解释一下第2个为什么和第1个一样?

SQL问个基础例子,书上的,我怎么看都看不懂..谁帮我解释一下第2个为什么和第1个一样?

SELECT
    id,
    name,
    cid
from
    shbooks
where
    cid=(
        SELECT
            cid 
        FROM
            shbooks
        where
            name= '光荣与梦想'
        );

上面这个我完全看得懂,返回<光荣与梦想>的cid,然后用这个值作为条件,匹配整个表的cid;


SELECT
    b1.id,
    b1.name,
    b1.cid
from
    shbooks b1,
    shbooks b2 
where
    b1.cid=b2.cid
and
    b2.name='光荣与梦想';

但是这个,条件是 b1.cid=b2.cid 的话,会返回整个表,为什么加上个 b2.name='光荣与梦想' 就能返回 和 光荣与梦想 相同cid 的别的书???


答案不在长,也不在语言是不是准确,只要让我能明白怎么个逻辑就行了..谢谢了!


@碎镜 他的是正解,先笛卡尔集,然后进行筛选。这是是实现原理。不过一般这种语句SQL会自动优化。并不会真的先做出笛卡尔积然后进行筛选。


原始

b1.cid b1.name
1     光荣与梦想
2     另一本书
1     梦想与光荣

条件b1.cid = b2.cid(从9个结果中过滤得到5个结果)只要理解为什么是9个结果,整个问题应该也没有什么疑问了。

b1.cid b1.name b2.cid b2.name
1     光荣与梦想 1    光荣与梦想
1     光荣与梦想 1    梦想与光荣
2     另一本书   2    另一本书
1     梦想与光荣 1    梦想与光荣
1     梦想与光荣 1    光荣与梦想

条件 b2.name='光荣与梦想'
就得到

b1.cid b1.name b2.cid b2.name
1     光荣与梦想 1    光荣与梦想
1     梦想与光荣 1    光荣与梦想

我就是提问的的人,这是我补充的!
我给大家解释解释到底是怎么回事,
其实逻辑就是自己把自己当俩表;
然后算自己的的笛卡尔集,
然后再用第二个条件筛选!

看成两个不同的表就行,这是自联接


条件是两个啊大兄弟,b2.name='光荣与梦想' 同时 b1.cid = b2.cid


你的第一种写法如果存在多条cid是不是就出错了?
你可以参考下面的写法:

/*子查询*/
select id,name,cid 
  from shbooks 
where cid in (select cid from shbooks where name='');

--或者这种写法
select id,name,cid
  from shbooks outerquery
where cid exists  
  (select 1 from shbooks innerquery where outerquery.cid = innerquery.cid and innerquery.name='');
  

至于你的第二种写法,你了解inner join吗?你看看下面的写法是不是更好懂些?

select id,name,cid
  from shbooks main
  inner join (select cid from shbooks where name = '') child
  on main.cid = child.cid; 

select id,name,cid
  from shbooks main
  inner join shbooks child on main.cid = child.cid
  where child.name = ''; 

最后问问,你都是按书上例子写的?如果是,我建议最好不要看那本书了!

【热门文章】
【热门文章】