在MySQL表卡中,每次将信用卡余额从一张卡转移到另一张卡时,ToCard有1行。
create table cardToCard (
id int,
dt date,
card_from int,
card_to int,
amount decimal(6,2),
primary key (id)
);
insert into cardToCard values (1, '2014-01-01', 100, 101, 200.00);
insert into cardToCard values (2, '2014-01-01', 101, 102, 200.00);
insert into cardToCard values (3, '2014-01-01', 102, 103, 200.00);
insert into cardToCard values (4, '2014-01-01', 103, 104, 200.00);
insert into cardToCard values (5, '2014-01-01', 104, 100, 200.00);
insert into cardToCard values (6, '2014-01-01', 99, 104, 200.00);
查询哪张卡已被使用过3次或更多次。
select card, count(*) 'count'
from
(
select card_from 'card', dt
from cardtocard
union all
select card_to 'card', dt
from cardtocard
) d
group by card
having count >= 3
结果是正确的。问题是将此写为自联接会更有效吗?
答案 0 :(得分:2)
编写此查询的最有效方法可能是从卡片列表开始,然后执行:
select c.card,
((select count(*) from cardTocard ctc where ctc.card_from = c.card) +
(select count(*) from cardTocard ctc where ctc.card_to = c.card)
) as cnt
from cards c
having cnt >= 3;
然后,您需要两个索引:cardTocard(card_from)
和cardTocard(card_to)
。
这应该使用聚合索引,这通常比文件排序快。
编辑:
使用您正在使用的结构,在子查询和外部查询中进行聚合会更快:
select card, sum(cnt) as cnt
from ((select card_from as car, count(*) as cnt
from cardtocard
group by card_from
) union all
(select card_to as card, count(*) as cnt
from cardtocard
group by card_to
)
) d
group by card
having count >= 3;
这可以更快,因为子查询的数据量小于union
将它们放在一起。