1
qdvictory 2012-07-23 13:51:29 +08:00
select aid from a where bid=47 or bid =22;
|
2
yokle 2012-07-23 13:51:38 +08:00
select aid from a WHERE bid in (47,22)
|
3
ichigo 2012-07-23 13:51:50 +08:00
in
|
4
yyai3 2012-07-23 13:52:24 +08:00
select aid from a where bid=47 or bid=22 order by aid
|
5
kingwkb OP |
7
yyai3 2012-07-23 13:59:03 +08:00
select b.aid from a b inner join a c where b.aid=c.aid and b.bid=47 and c.bid =22
|
8
qdvictory 2012-07-23 13:59:47 +08:00
select aid from a where bid=47 and aid in (select aid from a where bid = 22);
|
10
yyai3 2012-07-23 14:14:08 +08:00
select aid,count(*) from a where bid in () group by aid having count(*)=n
|
11
yyai3 2012-07-23 14:18:30 +08:00
要改成count(distinct bid) 去重吧
|
12
qdvictory 2012-07-23 14:22:39 +08:00
select * from (select if(count(*) > num,aid,0) as cid from a where bid in (22,47,...) group by cid order by cid desc) as s where s.cid != 0;
这是咋设计的表啊。。。 |
13
alsotang 2012-07-23 14:26:00 +08:00
我的答案跟#7一样
select aid from a as a1 inner join a as a2 where a1.bid = 47 and a1.bid = 22 and a1.aid = a2.aid @yyai3 |
15
kingwkb OP |
18
yokle 2012-07-23 14:59:23 +08:00
回头一看 这么多人 回答了。 这氛围不错 +1
|
19
colincat 2012-07-23 15:08:33 +08:00
@kingwkb 这不就是子类和父类的关系吗?
tagkey tag_f_id tag_name 1 0 读书 2 1 科幻类 3 1 教育类 4 2 国内仙剑 5 0 电影 以上tag代表标签的主键 tag_f_id代表父节点ID 0代表是最高节点 然后 这就类似递归。不知道是不是你想要的 |
20
alsotang 2012-07-23 15:10:15 +08:00
@kingwkb 我觉得你这个问题应该是个比较经典的设计问题,可能你的这个方法已经算是比较常见的解决办法了吧。我对于SQL的接触比较少,但是在Rails中的话....has_many会自动处理好这些问题,建议楼主google一下,应该就会得到答案了。我提供提供关键字吧:“rails hasmany SQL 如何设计”,试试这个。
|
22
colincat 2012-07-23 15:15:00 +08:00
@alsotang 是的 需要这样,但是你可以用这个表构建一个数据结构,预先生成一个tree,只有在有新变动的时候需要重新生成tree,如果他说的是一种频道的话,可能变化应该不是很大吧
|
23
ipconfiger 2012-07-23 15:25:01 +08:00
(SELECT `aid` FROM `表a` WHERE `bid`=22) INTERSECT (SELECT `aid` FROM `表a` WHERE `bid`=47)
原因,用 `bid`=22 or `bid`=47 这个查询条件 或者 `bid` in (22,47),在mysql里都会丢索引,也就是会产生全表扫描,所以把每个条件单独用字查询取出后用INTERSECT取交集,即可解决 |
24
alsotang 2012-07-23 15:32:53 +08:00
@ipconfiger 问一下这位牛人..我13L的解答,效率上如何,跟您23楼这个比较的话呢...
(本人SQL处于入门水平) |
25
kingwkb OP @ipconfiger mysql是不支持INTERSECT的
|
26
ipconfiger 2012-07-23 16:46:34 +08:00 1
|
27
kingwkb OP |
28
alsotang 2012-07-23 22:47:09 +08:00
@ipconfiger 是select aid from a as a1 inner join a as a2 where a1.bid = 47 and a1.bid = 22 and a1.aid = a2.aid,没有group by。你要表达的是inner join?
|
29
ipconfiger 2012-07-24 00:08:08 +08:00
@alsotang 你没跑过你的SQL吧,会报错的,亲。给你修改一下改成
select a1.aid from a as a1 inner join a as a2 where a1.bid = 47 and a1.bid = 22 and a1.aid = a2.aid; 这下不报错了,结果返回 Empty set (0.00 sec) 用我的sql实验,返回的是 +------+ | aid | +------+ | 100 | +------+ 1 row in set (0.00 sec) 我建的测试数据库数据和LZ给出的一致。 explain分析一下你的语句就知道错误在那里了 mysql> EXPLAIN -> select a1.aid from table_a as a1 inner join table_a as a2 where a1.bid = 47 and a1.bid = 22 and a1.aid = a2.aid; +----+-------------+-------+------+---------------+------+---------+------+------+------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+-------+------+---------------+------+---------+------+------+------------------+ | 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Impossible WHERE | +----+-------------+-------+------+---------------+------+---------+------+------+------------------+ Impossible WHERE |
30
alsotang 2012-07-24 00:29:59 +08:00
@ipconfiger 写写指正。还请问,效率呢?对于index的使用呢?
|
31
ipconfiger 2012-07-24 09:20:09 +08:00
@alsotang 你那条错误的sql就不用纠结效率了,根本的不出正确结果效率是无用的。对于LZ这个命题的效率问题我之前说过了,很难有特别高效的写法,层层嵌套的IN 子查询或者 EXISTS 子查询的方式可以保证不会丢失索引,但是过多潜逃的子查询会产生大量的临时表,且排序的时候如果不是根据bid排序还会产生filesort消耗CPU和内存。修改一下设计,用冗余数据来空间换时间比较好
|
32
napoleonu 2012-07-28 02:31:47 +08:00
我造了点数据,测试了下。
mysql> show create table d\G *************************** 1. row *************************** Table: d Create Table: CREATE TABLE `d` ( `aid` int(11) DEFAULT NULL, `bid` int(11) DEFAULT NULL, KEY `idx1` (`aid`,`bid`), KEY `idx2` (`bid`,`aid`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 1 row in set (0.00 sec) mysql> select count(*) from d; +----------+ | count(*) | +----------+ | 465005 | +----------+ 1 row in set (0.36 sec) mysql> select count(*) from (select count(*) from d group by aid,bid) t1; +----------+ | count(*) | +----------+ | 465005 | +----------+ 1 row in set (0.29 sec) mysql> select aid,count(*) from d group by aid; +------+----------+ | aid | count(*) | +------+----------+ | 1 | 16640 | | 2 | 16640 | | 3 | 16640 | | 4 | 16640 | | 5 | 16640 | | 6 | 33197 | | 7 | 32448 | | 11 | 16640 | | 12 | 16640 | | 13 | 16640 | | 14 | 16640 | | 15 | 16640 | | 16 | 16640 | | 17 | 16640 | | 21 | 16640 | | 22 | 16640 | | 23 | 16640 | | 24 | 16640 | | 25 | 16640 | | 26 | 16640 | | 31 | 16640 | | 32 | 16640 | | 33 | 16640 | | 34 | 16640 | | 35 | 16640 | | 36 | 16640 | +------+----------+ 26 rows in set (0.22 sec) mysql> select count(*) from d where aid=7; +----------+ | count(*) | +----------+ | 32448 | +----------+ 1 row in set (0.03 sec) mysql> select count(*) from d where aid=6; +----------+ | count(*) | +----------+ | 33197 | +----------+ 1 row in set (0.03 sec) mysql> select sql_no_cache bid from d where aid=6 and bid in (select bid from d where aid=7); | 331800 | | 332000 | | 332200 | | 332400 | | 332600 | | 332800 | +--------+ 18221 rows in set (0.12 sec) mysql> select sql_no_cache bid from d where aid in (6,7) group by bid having count(*)=2; | 331800 | | 332000 | | 332200 | | 332400 | | 332600 | | 332800 | +--------+ 18221 rows in set (0.08 sec) mysql> select sql_no_cache t1.bid from d t1 ,d t2 where t1.aid=6 and t2.aid=7 and t1.bid=t2.bid; | 331800 | | 332000 | | 332200 | | 332400 | | 332600 | | 332800 | +--------+ 18221 rows in set (0.11 sec) |
33
napoleonu 2012-07-28 02:35:12 +08:00 1
select sql_no_cache bid from d where aid=6 and bid in (select bid from d where aid=7);
select sql_no_cache bid from d where aid in (6,7) group by bid having count(*)=2; select sql_no_cache t1.bid from d t1 ,d t2 where t1.aid=6 and t2.aid=7 and t1.bid=t2.bid; 三条SQL语句都经过反复执行,所消耗的时间也都稳定在如上的时间上。 就这个数据量来说,似乎 select sql_no_cache bid from d where aid in (6,7) group by bid having count(*)=2; 效率最高。 |
34
kingwkb OP @napoleonu 你这个数据分布不好,虽然数据大,但aid, bid分布太少,group by aid和group by aid, bid至少也得达到上千个吧。
|