对于您提供的样本数据,我达到了 66%?“黄油”有 3 笔交易,其中只有 2 笔交易包括“果酱”。
我使用了以下测试表。
create table transactions(
trans_no varchar(5) not null
,item varchar(20) not null
,primary key(trans_no, item)
);
insert into transactions(trans_no, item)
values ('T1', 'butter')
,('T1', 'jam')
,('T2', 'butter')
,('T3', 'bread')
,('T3', 'ice cream')
,('T4', 'butter')
,('T4', 'jam');
以下是我的回答尝试。内部选择查找所有包含“黄油”的交易。对于每个这样的交易,它还设置一个标志(bought_jam),说明该交易是否还包括“jam”。(having 子句不包括包含“jam”但不包含“butter”的交易)。
在外层选择中,我基本上对所有的行进行计数(计数对应于包括黄油在内的事务数),并对 jam flag 求和,它对应于包括黄油和 jam 的事务数。
select sum(bought_jam) as jams_bought
,count(*) as num_trans
,100 * sum(bought_jam) / count(*) as correlation_pct
from (select trans_no
,max(case when item = 'jam' then 1 else 0 end) as bought_jam
from transactions
where item in('butter', 'jam')
group
by trans_no
having min(case when item = 'butter' then item end) = 'butter'
) butter_trans;
上面的查询给出以下结果:
+-------------+-----------+-----------------+
| jams_bought | num_trans | correlation_pct |
+-------------+-----------+-----------------+
| 2 | 3 | 66.6667 |
+-------------+-----------+-----------------+
1 row in set (0.00 sec)
让我知道这对你有什么影响。
编辑:
以下查询会给出相同的结果,但更容易阅读。但是,如果 transactions 表非常大,并且item = x
不是很有选择性(返回很多行),这个查询几乎肯定会更慢。
select count(t2.trans_no) as jams_bought
,count(*) as num_trans
,count(t2.trans_no) / count(*) as correlation_pct
from transactions t1
left join transactions t2 on(t2.trans_no = t1.trans_no and t2.item = 'jam')
where t1.item = 'butter';