跳至主要內容
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?

4563博客

全新的繁體中文 WordPress 網站
  • 首頁
  • 话说这两个 sql 为啥和我预想的不太一样
未分類
18 10 月 2020

话说这两个 sql 为啥和我预想的不太一样

话说这两个 sql 为啥和我预想的不太一样

資深大佬 : luxinfl 5

select * from t1  where  not exists (select 1 from t2 where t1.name = t2.name)  select * from t1  where exists (select 1 from t2 where t1.name != t2.name) 

我本意是找 t1 比 t2 多的数据,结果把 t1 的所有东西都返回了

大佬有話說 (24)

  • 資深大佬 : BrettD

    为啥要这样写

  • 主 資深大佬 : luxinfl

    @BrettD 因为不存在嘛。。。

  • 主 資深大佬 : luxinfl

    话说换成 in,比较容易看出来一下吧,应该是等价于
    “`
    select * from t1 where not in(select name from t2)
    第二个好像不太对
    “`

  • 資深大佬 : wisunny

    翻译成汉语就好理解多了,一个是不存在相等的,一个是存在不等的。而存在不等的只要存在一个就始终为 true,结果自然不一样

  • 資深大佬 : chendy

    select 1 from t2 where t1.name != t2.name 这个…只要有不同的就有返回,于是就返回全部呗

  • 主 資深大佬 : luxinfl

    @wisunny 那这个怎么遍历的啊,感觉怪怪的

  • 主 資深大佬 : luxinfl

    @chendy 所以说第二个 sql 就相当于直接 select * from t1 ?

  • 資深大佬 : chendy

    @luxinfl 也不是但是差不多,只要 t2 有数据,而且不全都和 t1 的 name 一样就有返回

  • 資深大佬 : kiracyan

    select * from t1 where name not in (select name from t2)

  • 資深大佬 : no1xsyzy

    @luxinfl 除非 t2 里只有一条
    把 SQL 重新写为集合推导式:

    式 1 等价于
    { x | x in t1, neg exists_{y in t2} (x.name = y.name) }
    = { x | x in t1, forall_{y in t2} (x.name neq y.name) }

    式 2 等价于
    { x | x in t1, exists_{y in t2} (x.name neq y.name) }

    你觉得一样吗?

  • 主 資深大佬 : luxinfl

    @chendy 但是我 t1 和 t2 的表数据一样,第二个 sql 还是有返回啊

  • 資深大佬 : YYYYMMDDHHSS

    翻译:1,对于 T1 的某一行,只要存在一行 T2.NAME == T1.NAME,就返回 T1.*;
    2,对于 T1 的某一行,只要存在一行 T2.NAME <> T1.NAME.就返回 T1.*; 那么哪怕真的只有一个 name 不在 T1 中,对于任何一个 T1 行都满足….

  • 資深大佬 : no1xsyzy

    话说
    select * from t1 where name not in (select name from t2)
    和
    select t1.* from t1 left join t2 on t1.name = t2.name where t2.name = null
    两个相比效率如何?

    但第二个可读性太差了,又要 t1.name = t2.name 又要 t2.name = null…… 还是我的(奇技淫巧)写法有问题?
    如果效率只稍高一点还是不要用 2,如果效率提升非常高那就加注释

  • 資深大佬 : no1xsyzy

    @luxinfl 注意 “不全都和”
    这个 name 被认为 TLD 太傻了……
    顺便试试:
    `t1`.name [t1].name

  • 資深大佬 : wolfie

    t2 如果是空表,exists 直接返回 false 。
    第二条 sql 跟你需求不一样。

  • 主 資深大佬 : luxinfl

    @no1xsyzy 第一个是不是相当于
    for x in t1:
    for y in t2:
    if(x.name == y.name):
    result.add(x)
    break;

  • 主 資深大佬 : luxinfl

    @luxinfl 不对,条件写错了。。。

  • 資深大佬 : no1xsyzy

    @luxinfl 啊,用 Python 解释的话这么写吧:
    式 1:
    [x for x in t1 if not any(x[‘name’] == y[‘name’] for y in t2)]
    根据反演律展开,其等价于
    [x for x in t1 if all(x[‘name’] != y[‘name’] for y in t2)]

    式 2:
    [x for x in t1 if any(x[‘name’] != y[‘name’] for y in t2)]

    一个是 all 一个是 any

  • 主 資深大佬 : luxinfl

    @no1xsyzy 谢谢大佬,这么看我就懂了。。

  • 資深大佬 : samv2

    找 t1 比 t2 多的,可以这样写
    select t1.* from t1
    left join t2
    on t1.name=t2.name
    where t2.name is null

  • 資深大佬 : c6h6benzene

    @no1xsyzy #13 第二个就是标准的 sql 啊,一天到晚都写这种,name=name 是连接条件,where 是限制条件,不会读混的。另外要用 is null

  • 資深大佬 : xdsty

    直接左连接找悬空的记录就可以了

  • 主 資深大佬 : luxinfl

    @samv2 这个是可以,我只是没搞太懂 exists 和 not exists 怎么玩的

  • 資深大佬 : xiyangzuile

    第二条是因为 内部查询判断 t1.name !=t2.name 会导致永远都返回 true , 所以返回结果是 t1 的所有结果

文章導覽

上一篇文章
下一篇文章

AD

其他操作

  • 登入
  • 訂閱網站內容的資訊提供
  • 訂閱留言的資訊提供
  • WordPress.org 台灣繁體中文

51la

4563博客

全新的繁體中文 WordPress 網站
返回頂端
本站採用 WordPress 建置 | 佈景主題採用 GretaThemes 所設計的 Memory
4563博客
  • Hostloc 空間訪問刷分
  • 售賣場
  • 廣告位
  • 賣站?
在這裡新增小工具