喜悦国际村's Archiver

选择网速最快的镜像: 北京联通 | 美国加州Fremont | 美国宾州Scranton .

menses 发表于 2010-3-4 05:26 PM

一道mysql的题目

[i=s] 本帖最后由 menses 于 2010-3-4 05:31 PM 编辑 [/i]

数据库类型 mysql
一张关系表,就两个字段
colA,colB    关系为一个colA对应多个colB
1,123
1,234
1,345
2,123
2,345
1)求: colB值为123和234(and的关系,两个条件都满足) colA的值 的sql写法
2)求: colB值为123或者234(or的关系,满足一个就可以) colA的值 的sql写法
3)求: colB值为123不等于234(满足前一个且后面一个不满足) colA的值 的sql写法
(注这张表有1000W条记录,每个colA对应100条colB,要考虑性能)

menses 发表于 2010-3-5 09:46 AM

没人回,这贴子要沉了

游戏人间 发表于 2010-3-5 05:23 PM

消灭零回复贴

游戏人间 发表于 2010-3-5 05:25 PM

不过你自己读一下你的要求,至少我看了好几遍才弄明白你在说什么。特别是最后一条(满足前一个且后面一个不满足),colB值为123之后肯定就不可能再等于234了,后面这条件还有必要吗。“=”号是SQL语句中最小集合了...

newmewo 发表于 2010-3-19 12:35 AM

[i=s] 本帖最后由 newmewo 于 2010-3-19 12:36 AM 编辑 [/i]

读了内容,大概知道要什么样的查询了。
我只会做简单的链表查询。
都满足的 简单点
同时满足 select * from table ta left join table tb on ta.colA = tb.colA wehre ta.colB = 123 and tb.colB=234
满足其一 select * from table where colB = 123 or colb =234
满足其中一个,并且另外一个不满足
select * from table ta left join table tb on ta.colA = tb.colA, tb.colB =234 wehre ta.colB = 123 and tb.colB IS NULL

hhsw 发表于 2010-3-19 10:35 AM

楼上正解!

newmewo 发表于 2010-3-20 04:38 AM

似乎第三个应该修正一下 由
select * from table ta left join table tb on ta.colA = tb.colA, tb.colB =234 wehre ta.colB = 123 and tb.colB IS NULL

修改为
select * from table ta left join table tb on ta.colA = tb.colA AND  tb.colB =234 wehre ta.colB = 123 and tb.colB IS NULL

left join 似乎应该用 And 做连接,不应该用逗号(,) 把, 不知道逗号能不能行得通。 翻了个错误,没测试,哎~

ljf841 发表于 2010-3-22 03:45 PM

楼上的语法是没问题,性能肯定不是很好。
我来抛个砖吧
SELECT colA FROM table WHERE colB in (234,123) group by colA having count(distinct colB)>2
我自己测试了下,在1000w的记录下,楼上的语句执行了3秒多,我的语句执行了0.0263 秒

menses 发表于 2010-3-22 05:23 PM

谢谢楼上的,我其实自己也找到的方法,和你的方法差不多

newmewo 发表于 2010-3-22 11:30 PM

ljf841 说的是啊。 原本做两次表扫描的,现在做一次。

这样的语句完全可以取代 第一种要求,第二种 or 的查询就没必要换了
对于第三种。那就更应该替换了。不然效率真的是糟糕透顶。

手册上说把 in(123,234)换成 =123 or =234 效率更佳。

ljf841 发表于 2010-3-23 11:46 AM

对于in 和 or 楼上好像说反了吧,in 比 or更好
我自己测试了下 or的时间是in的3倍

newmewo 发表于 2010-3-25 04:16 AM

是吗? IN 比 or 效果更好?

难道我记反了? 你确定? 我怎么记得不是这样的啊。 赶紧翻手册去。回头再说。

newmewo 发表于 2010-3-25 04:45 AM

又读了一遍关于优化介绍。
in(123,234) 和 =123 or =234 其实没多大差别。

不过印象深刻的是这部分

13.2.8.10. 优化子查询
开发过程不断进展,所以从长远来看,没有一个可靠的优化技巧。有些技巧您可能会感兴趣,并原意采用:

·         有些子句会影响在子查询中的行的数量和顺序。
·         用子查询替换联合。(这个我比较吃惊。因为老版本mysql不支持子查询)
·         部分子查询可以被转换为联合,以便与不支持子查询的旧版本的MySQL相兼容。不过,在有些情况下,把子查询转化为联合可以提高效果。(这里又说转化成联合可以提高效率。与上条有出入,我都晕了)
·         把子句从子查询的外部转移到内部。(这个主要是给的例子比较经典)
另一个例子是,使用此查询:
SELECT (SELECT column1 + 5 FROM t1) FROM t2;
代替此查询:
SELECT (SELECT column1 FROM t1) + 5 FROM t2;
看了好半天,没理解这条的精髓,谁帮忙讲讲。 例子够经典。好在我没吃透。

·         使用行子查询,代替关联子查询。举例说明,使用此查询:
·         对于只返回一行的无关联子查询,IN的速度慢于=。举例说明,使用此查询:

ljf841 发表于 2010-3-25 05:12 PM

这个讨论越来越有意思了 :)
SELECT (SELECT column1 + 5 FROM t1) FROM t2; 和 SELECT (SELECT column1 FROM t1) + 5 FROM t2;这两个例子非常好,我感觉是这样的,第一条直接把一个结果集作为一个列返回,而第二条还要把结果集带入到公式运算,所以第一条的结果为好。这个例子的用意在我们尽量把运算放在列上,而不是子查询的结果集上,不知道理解对否。
关于in和or 据我的测试,in比or要快一点点

newmewo 发表于 2010-3-25 08:53 PM

这两个查询时一样的结果。
可不理解这样的查询是用来做什么用的。
因为本身就看不懂这样的子查询。所以不理解这么修改后的好处到底是什么。
select (select column1 from t1) from t2
按照给的例子, 上面的查询应该是有意义的。
这个查询的结果是什么?

难道是这样:
表 t1 有一个栏目 column1 ,
有n行,比如 1;2;3;4;5;6;7 比如有7行
t2 结构有 1,2,3,4,5,6,7 几个栏目
select (select column1 from t1) from t2;的结果是获取 select 1,2,3,4,5,6,7 from t2
是这样的?

页: [1]

Powered by Discuz! Archiver 7.0.0  © 2001-2009 Comsenz Inc.