sql查询-既买了产品A又买了产品B的用户

戴墨镜的虫子 2012-07-11 05:44:06
表结构
----------------------------------------------------------
id username product_id
1 张三 363
2 李四 364
3 张三 365
4 王五 363

需求:
找出既买了产品363又买了产品365的用户(即张三),sql怎么写?
数据量比较大,有没有不用表联结的写法?
...全文
2668 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
SQL77 2012-07-12
  • 打赏
  • 举报
回复
SELECT * FROM TB T
WHERE EXISTS(SELECT 1 FROM TB WHERE username=T.username AND product_id=363) AND
EXISTS(SELECT 1 FROM TB WHERE username=T.username AND product_id=365)
AND T.product_id IN(365,363)

--把product_id 单独一个索引
username 单独一个
先试试看。索引有没有效有作用还要看你的数据量。数据结构这些
语句按上面的。
戴墨镜的虫子 2012-07-12
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

引用 4 楼 的回复:
引用 2 楼 的回复:

SQL code
SELECT * FROM TB T
WHERE EXISTS(SELECT 1 FROM TB WHERE username=T.username AND product_id=363) AND
EXISTS(SELECT 1 FROM TB WHERE username=T.username AND produ……
[/Quote]

username加了btree索引,product_id是int型的,没加索引,请问这样有问题吗?还有没有更好的办法
SQL77 2012-07-12
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
引用 2 楼 的回复:

SQL code
SELECT * FROM TB T
WHERE EXISTS(SELECT 1 FROM TB WHERE username=T.username AND product_id=363) AND
EXISTS(SELECT 1 FROM TB WHERE username=T.username AND product_id=365)


……
[/Quote]
如果就两个product_id还慢。那只能是说你索引不行
SQL77 2012-07-12
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]
引用 2 楼 的回复:

SQL code
SELECT * FROM TB T
WHERE EXISTS(SELECT 1 FROM TB WHERE username=T.username AND product_id=363) AND
EXISTS(SELECT 1 FROM TB WHERE username=T.username AND product_id=365)


……
[/Quote]
如果就两个product_id还慢。那只能是说你索引不行
戴墨镜的虫子 2012-07-12
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 的回复:]

select * from tb a,
(SELECT username FROM TB WHERE product_id=363) b
(SELECT username FROM TB WHERE product_id=365) c
where b.username=c.username and a.username=c.username
[/Quote]

就是要避免多表联结情况出现,表联结效率低。
quchen520 2012-07-12
  • 打赏
  • 举报
回复
select * from tb a,
(SELECT username FROM TB WHERE product_id=363) b
(SELECT username FROM TB WHERE product_id=365) c
where b.username=c.username and a.username=c.username
戴墨镜的虫子 2012-07-12
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

SQL code
select
*
from
tb
where
username in(select username from tb group by username having count(1)=2)
and
product_id in('363','365')
[/Quote]

查出来的username会很多的,如果用in效率会很低。
--小F-- 2012-07-12
  • 打赏
  • 举报
回复
select
*
from
tb
where
username in(select username from tb group by username having count(1)=2)
and
product_id in('363','365')
戴墨镜的虫子 2012-07-12
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

SQL code
SELECT * FROM TB T
WHERE EXISTS(SELECT 1 FROM TB WHERE username=T.username AND product_id=363) AND
EXISTS(SELECT 1 FROM TB WHERE username=T.username AND product_id=365)
[/Quote]

我试了一下,效率低的难以忍受。
戴墨镜的虫子 2012-07-12
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

表达不是问题,具体看你数据怎么选择和操作。
SQL code

with t1 as
(
select Username, product_id
from tablename
where product_id = 363
group by Username, product_id
),
t2 as
(
select Username, product_id
from tablename
wh……
[/Quote]

兄台是mssql的写法 mysql中没有这种写法,有没有其它的实现方案
戴墨镜的虫子 2012-07-12
  • 打赏
  • 举报
回复
[Quote=引用 19 楼 的回复:]

SELECT distinct username FROM TB
试试这个语句有多少数据
[/Quote]

70多W
quchen520 2012-07-12
  • 打赏
  • 举报
回复
SELECT distinct username FROM TB
试试这个语句有多少数据
戴墨镜的虫子 2012-07-12
  • 打赏
  • 举报
回复
[Quote=引用 16 楼 的回复:]

引用 15 楼 的回复:
引用 12 楼 的回复:

SELECT * FROM TB T
WHERE EXISTS(SELECT 1 FROM TB WHERE username=T.username AND product_id=363) AND
EXISTS(SELECT 1 FROM TB WHERE username=T.username AND product_id=36……
[/Quote]

363,365过滤后大概数据量在5万到15万之间
username include(product_id)再试试--这个没明白你的意思
quchen520 2012-07-12
  • 打赏
  • 举报
回复
你查询363,365多少数据量?
username include(product_id)再试试

+1
SQL77 2012-07-12
  • 打赏
  • 举报
回复
[Quote=引用 15 楼 的回复:]
引用 12 楼 的回复:

SELECT * FROM TB T
WHERE EXISTS(SELECT 1 FROM TB WHERE username=T.username AND product_id=363) AND
EXISTS(SELECT 1 FROM TB WHERE username=T.username AND product_id=365)
AND T.produc……
[/Quote]
你查询363,365多少数据量?
username include(product_id)再试试
戴墨镜的虫子 2012-07-12
  • 打赏
  • 举报
回复
[Quote=引用 12 楼 的回复:]

SELECT * FROM TB T
WHERE EXISTS(SELECT 1 FROM TB WHERE username=T.username AND product_id=363) AND
EXISTS(SELECT 1 FROM TB WHERE username=T.username AND product_id=365)
AND T.product_id IN(36……
[/Quote]

username是单独建了索引的,之前product_id也是有索引的,不过product_id是int类型,我试了一下,不加索引会更快一些。
戴墨镜的虫子 2012-07-12
  • 打赏
  • 举报
回复
[Quote=引用 13 楼 的回复:]

我觉得问题出在username的比较这个地方;
他里面是中文的所以会比较慢,而且数据量很大

你可以测下
SELECT 1 FROM TB a, tb b WHERE a.username=b.username
如果这条语句也很慢的话那就是我说的这个原因了。
[/Quote]

数据量是有点大,有100多万,不过username都是英文的。
直接用你这条语句不加限定条件的话会Out of memory
quchen520 2012-07-12
  • 打赏
  • 举报
回复
我觉得问题出在username的比较这个地方;
他里面是中文的所以会比较慢,而且数据量很大

你可以测下
SELECT 1 FROM TB a, tb b WHERE a.username=b.username
如果这条语句也很慢的话那就是我说的这个原因了。
SQL77 2012-07-11
  • 打赏
  • 举报
回复
SELECT * FROM TB T 
WHERE EXISTS(SELECT 1 FROM TB WHERE username=T.username AND product_id=363) AND
EXISTS(SELECT 1 FROM TB WHERE username=T.username AND product_id=365)
shoppo0505 2012-07-11
  • 打赏
  • 举报
回复
表达不是问题,具体看你数据怎么选择和操作。

with t1 as
(
select Username, product_id
from tablename
where product_id = 363
group by Username, product_id
),
t2 as
(
select Username, product_id
from tablename
where product_id = 365
group by Username, product_id
)
select Username
from t1
where Username in
(select Username
from t2)


34,590

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧