id primary key
username varchar
id primary key
money int
member_id foreign key
id primary key
price int
member_id foreign key
mpoints
和gpoints
几乎与members
表格相同,我需要找出money
和price
之和的数据> 200&count> 2,这是我的解决方案
SELECT
`t`.`username`, `t`.`p`
FROM
(
SELECT
`members`.`username`,
`price` AS `p`
FROM
`members`
LEFT JOIN `gpoints` ON `members`.`id` = `gpoints`.`member_id`
UNION ALL
SELECT
`members`.`username`,
`money` AS `p`
FROM
`members`
LEFT JOIN `mpoints` ON `members`.`id` = `mpoints`.`member_id`
) AS `t`
GROUP BY `t`.`username`
HAVING COUNT(`t`.`p`) >= 2 AND `t`.`p` > 200
但是会员超过五百万,两个积分表都超过五万,所以查询速度很慢,我可以通过调整查询来提高性能吗?
答案 0 :(得分:2)
我只会将gpoints和mpoints表联合起来,按该联合的member_id分组,并将该数据集加入到成员表中:
select
m.username,
t.p
from members as m
inner join (
select
p.member_id,
sum(p) as p
from (
select
member_id,
price as p
from gpoints
union all
select
member_id,
money as p
from mpoints
) as p
group by
member_id
having
count(p.p) >=2
and sum(p.p) > 200
) t
on t.member_id = m.id
或者,您可以为每个表添加一个分组并添加这些总和:
select
m.username,
gp.p + mp.p as p
from members as m
left join (
select
member_id,
sum(price) as p,
count(price) as cnt
from gpoints
group by member_id
) gp
on gp.member_id = m.id
left join (
select
member_id,
sum(money) as p,
count(money) as cnt
from mpoints
group by member_id
) mp
on mp.member_id = m.id
where
ifnull(gp.p,0) + ifnull(mp.p,0) > 200
and ifnull(gp.cnt,0) + ifnull(mp.cnt,0) >= 2
答案 1 :(得分:0)
您的正确查询将是:
SELECT t.username, SUM(t.p) as p
FROM (SELECT m.username, price AS p
FROM members m LEFT JOIN
gpoints g
ON m.id = g.member_id
UNION ALL
SELECT m.username, `money` AS p
FROM members m LEFT JOIN
mpoints p
ON m.id = p.member_id
) t
GROUP BY t.username
HAVING COUNT(t.p) >= 2 AND SUM(t.p) > 200;
请注意SUM()
和SELECT
中使用HAVING
。
为了获得更好的性能,您需要gpoints(member_id, price)
和mpoints(member_id, money)
上的索引。