r***o 发帖数: 1526 | 1 一个 table
ID UserID Region
------------------
1 1 A
2 1 B
3 1 C
4 2 B
5 2 C
6 3 B
7 3 C
现在要把所有只Map到Region B和C的UserID找出来,这个query怎么写
Query的最后结果应该是2,3 |
e****7 发帖数: 4387 | 2 select userid
from table
where region in('b','c')
group by userid
用select distinct 也行
这个是tsql 的,不保证其它 |
r***o 发帖数: 1526 | 3 不行, 最后结果会是1,2,3 不是2,3
【在 e****7 的大作中提到】 : select userid : from table : where region in('b','c') : group by userid : 用select distinct 也行 : 这个是tsql 的,不保证其它
|
e****7 发帖数: 4387 | 4 理解错了
select userid from table
where region = 'b' and userid in (
select userid from table&
#160;whereregion = 'c'
) and userid not in (
select userid from table&
#160;whereregion = 'a'
) |
w*r 发帖数: 2421 | 5 这种作业问题要么不写,要写就要有点水品
用in/notin的同学,你会被DBA抓去修理
相反,如果写成这样, 你的DBA一般会有下面两种反应中的一种
A 含羞小碎步弹开
B 含笑拈花不语
SELECT
USERID,
SUM(CASE WHEN REGION = 'B' THEN 1 ELSE 0 END )AS B_FLG,
SUM(CASE WHEN REGION = 'C' THEN 1 ELSE 0 END) AS C_FLG
FROM TABLE
GROUP BY USERID
HAVING B_FLG > 0 AND C_FLG > 0 |
E*****e 发帖数: 197 | 6 哈哈,学习了
我也是用 in/notin 来写的,好用就行呗 :)
【在 w*r 的大作中提到】 : 这种作业问题要么不写,要写就要有点水品 : 用in/notin的同学,你会被DBA抓去修理 : 相反,如果写成这样, 你的DBA一般会有下面两种反应中的一种 : A 含羞小碎步弹开 : B 含笑拈花不语 : SELECT : USERID, : SUM(CASE WHEN REGION = 'B' THEN 1 ELSE 0 END )AS B_FLG, : SUM(CASE WHEN REGION = 'C' THEN 1 ELSE 0 END) AS C_FLG : FROM TABLE
|
w*r 发帖数: 2421 | 7 when your table is 200 milliow rows, or 20B rows you will see the difference
【在 E*****e 的大作中提到】 : 哈哈,学习了 : 我也是用 in/notin 来写的,好用就行呗 :)
|
e****7 发帖数: 4387 | 8
学习了,哈哈
不过还是miss了LZ的一个req, 只要b,c. 还是要把a的去掉。
这个问题好似是给inclusion, exclusion 的应用。数据量大的话,DBA当然要打回从新
写。
【在 w*r 的大作中提到】 : 这种作业问题要么不写,要写就要有点水品 : 用in/notin的同学,你会被DBA抓去修理 : 相反,如果写成这样, 你的DBA一般会有下面两种反应中的一种 : A 含羞小碎步弹开 : B 含笑拈花不语 : SELECT : USERID, : SUM(CASE WHEN REGION = 'B' THEN 1 ELSE 0 END )AS B_FLG, : SUM(CASE WHEN REGION = 'C' THEN 1 ELSE 0 END) AS C_FLG : FROM TABLE
|
r***o 发帖数: 1526 | 9 不错
改了一下
table T
Region
------------
B
C
SELECT UserID FROM A LEFT OUTER JOIN T ON A.Region = T.Region
GROUP BY UserID HAVING COUNT( ISNULL(T.Region, 0) ) = 2
UserID和Region是Unique的,这样应该没问题了吧
-
【在 w*r 的大作中提到】 : 这种作业问题要么不写,要写就要有点水品 : 用in/notin的同学,你会被DBA抓去修理 : 相反,如果写成这样, 你的DBA一般会有下面两种反应中的一种 : A 含羞小碎步弹开 : B 含笑拈花不语 : SELECT : USERID, : SUM(CASE WHEN REGION = 'B' THEN 1 ELSE 0 END )AS B_FLG, : SUM(CASE WHEN REGION = 'C' THEN 1 ELSE 0 END) AS C_FLG : FROM TABLE
|
e****7 发帖数: 4387 | 10
不错,assume data doesn't have
1,2,b
2,2,b
的情况
可以改having count( distinct.....
【在 r***o 的大作中提到】 : 不错 : 改了一下 : table T : Region : ------------ : B : C : SELECT UserID FROM A LEFT OUTER JOIN T ON A.Region = T.Region : GROUP BY UserID HAVING COUNT( ISNULL(T.Region, 0) ) = 2 : UserID和Region是Unique的,这样应该没问题了吧
|
|
|
w*r 发帖数: 2421 | 11 不要随便改我的code啊,
当然你如果一定要说有用index join..我无语,我的解法只有一个table scan...而且
你用distinct的时候会trigger sort....
结论:改出来的都不好
【在 e****7 的大作中提到】 : : 不错,assume data doesn't have : 1,2,b : 2,2,b : 的情况 : 可以改having count( distinct.....
|
e****7 发帖数: 4387 | 12
呵呵,没改你的,改的是LZ的。完全不同的解决方案,我的改动只是增强了真对重复数
据的可能性。不是一定要的。
【在 w*r 的大作中提到】 : 不要随便改我的code啊, : 当然你如果一定要说有用index join..我无语,我的解法只有一个table scan...而且 : 你用distinct的时候会trigger sort.... : 结论:改出来的都不好
|
e****7 发帖数: 4387 | 13
你的解法还是1,2,3。不符合LZ的要求的。和我一开始的解法没差多少啊。。
【在 w*r 的大作中提到】 : 不要随便改我的code啊, : 当然你如果一定要说有用index join..我无语,我的解法只有一个table scan...而且 : 你用distinct的时候会trigger sort.... : 结论:改出来的都不好
|
e****7 发帖数: 4387 | |
e****7 发帖数: 4387 | 15
嗯,unique 就稳妥了,我没注意这个
【在 r***o 的大作中提到】 : 不错 : 改了一下 : table T : Region : ------------ : B : C : SELECT UserID FROM A LEFT OUTER JOIN T ON A.Region = T.Region : GROUP BY UserID HAVING COUNT( ISNULL(T.Region, 0) ) = 2 : UserID和Region是Unique的,这样应该没问题了吧
|
w*r 发帖数: 2421 | 16 哦,要求”只“map B and C
SELECT
USERID,
SUM(CASE WHEN REGION = 'B' THEN 1 ELSE 0 END )AS B_FLG,
SUM(CASE WHEN REGION = 'C' THEN 1 ELSE 0 END) AS C_FLG
SUM(CASE WHEN REGION not in ('B', 'C' ) THEN 1 ELSE 0 END) AS o_FLG
FROM TABLE
GROUP BY USERID
HAVING B_FLG > 0 AND C_FLG > 0 AND O_FLG = 0 |
e****7 发帖数: 4387 | 17
that's it, LZ的方案也不错
【在 w*r 的大作中提到】 : 哦,要求”只“map B and C : SELECT : USERID, : SUM(CASE WHEN REGION = 'B' THEN 1 ELSE 0 END )AS B_FLG, : SUM(CASE WHEN REGION = 'C' THEN 1 ELSE 0 END) AS C_FLG : SUM(CASE WHEN REGION not in ('B', 'C' ) THEN 1 ELSE 0 END) AS o_FLG : FROM TABLE : GROUP BY USERID : HAVING B_FLG > 0 AND C_FLG > 0 AND O_FLG = 0
|
n****e 发帖数: 1403 | 18 select distinct userid
from thisTable t1
where exists(select * from thisTable t2 where t2.userid = t1.userid and t2.
region = 'B' )
and exists(select * from thisTable t2 where t2.userid = t1.userid and t2.
region = 'C' )
and not exists(select * from thisTable t2 where t2.userid = t1.userid and
t2.region not in ('B','C') ) |
o******1 发帖数: 44 | 19 这样写,效率会比较高
select distinct userid from table where region='b'
intersect
select distinct userid from table where region='c' |
r***o 发帖数: 1526 | 20 其实B,C是从另外一个SELECT来的,hardcode B,C我这里没法用 |
|
|
e****7 发帖数: 4387 | 21
这个同样会得到1,2,3 为答案,还需要elimate 'a'
nice use of intersect though
【在 o******1 的大作中提到】 : 这样写,效率会比较高 : select distinct userid from table where region='b' : intersect : select distinct userid from table where region='c'
|
o******1 发帖数: 44 | 22 那就加一条except, 这样
select distinct userid from table where region='b'
intersect
select distinct userid from table where region='c'
except
select distinct userid from table where region='a' |
e****7 发帖数: 4387 | 23
perfect, i think this is exactly what they want
【在 o******1 的大作中提到】 : 那就加一条except, 这样 : select distinct userid from table where region='b' : intersect : select distinct userid from table where region='c' : except : select distinct userid from table where region='a'
|