我有一个表(变量(无限种类),attr(正好3个不同的属性),日期,状态(只能是0,1或2)):
------------------------------------
| Variable | Attr | Date | State |
|------------------------------------|
| V1 | A1 |01/01/14 | 0 |
| V1 | A1 |01/02/14 | 2 |
| V1 | A1 |01/03/14 | 1 |
| V1 | A1 |01/04/14 | 2 |
| V1 | A2 |01/01/14 | 1 |
| V1 | A2 |01/02/14 | 0 |
| V1 | A2 |01/03/14 | 1 |
| V1 | A2 |01/04/14 | 1 |
| V1 | A3 |01/01/14 | 0 |
| V1 | A3 |01/02/14 | 0 |
| V1 | A3 |01/03/14 | 1 |
| V1 | A3 |01/04/14 | 2 |
| V2 | A1 |01/01/14 | 2 |
| V2 | A1 |01/02/14 | 1 |
| V2 | A1 |01/03/14 | 2 |
| V2 | A1 |01/04/14 | 1 |
| V2 | A2 |01/01/14 | 1 |
| V2 | A2 |01/02/14 | 2 |
| V2 | A2 |01/03/14 | 1 |
| V2 | A2 |01/04/14 | 0 |
| V2 | A3 |01/01/14 | 1 |
| V2 | A3 |01/02/14 | 0 |
| V2 | A3 |01/03/14 | 2 |
| V2 | A3 |01/04/14 | 1 |
| V3 | A1 |01/01/14 | 1 |
| V3 | A1 |01/02/14 | 2 |
| V3 | A1 |01/03/14 | 1 |
| V3 | A1 |01/04/14 | 1 |
| V3 | A2 |01/01/14 | 1 |
| V3 | A2 |01/02/14 | 0 |
| V3 | A2 |01/03/14 | 0 |
| V3 | A2 |01/04/14 | 2 |
| V3 | A3 |01/01/14 | 1 |
| V3 | A3 |01/02/14 | 0 |
| V3 | A3 |01/03/14 | 2 |
| V1 | A3 |01/04/14 | 1 |
| . | . |. | . |
| Vn | An |n | n |
|----------|------|----------|-------|
我想要的输出(音符计数是此示例的完全随机值):
------------------------------------
| Variable | Attr | Count| State |
------------------------------------
| V1 | A1 | 50 | 0 |
| V1 | A1 | 24 | 1 |
| V1 | A1 | 22 | 2 |
| V1 | A2 | 1 | 0 |
| V1 | A2 | 0 | 1 |
| V1 | A2 | 15 | 2 |
| V1 | A3 | 68 | 0 |
| V1 | A3 | 9 | 1 |
| V1 | A3 | 34 | 2 |
| V2 | A1 | 10 | 0 |
| V2 | A1 | 0 | 1 |
| V2 | A1 | 25 | 2 |
| V2 | A2 | 48 | 0 |
| V2 | A2 | 96 | 1 |
| V2 | A2 | 14 | 2 |
| V2 | A3 | 12 | 0 |
| V2 | A3 | 3 | 1 |
| V2 | A3 | 0 | 2 |
| V3 | A1 | 4 | 0 |
| V3 | A1 | 5 | 1 |
| V3 | A1 | 8 | 2 |
| V3 | A2 | 19 | 0 |
| V3 | A2 | 95 | 1 |
| V3 | A2 | 26 | 2 |
| V3 | A3 | 4 | 0 |
| V3 | A3 | 85 | 1 |
| V3 | A3 | 50 | 2 |
| . | . |. | . |
| Vn | An |n | n |
|----------|------|------|-------|
我要做的第一件事就是选择一个变量+ attr + state组合,我想把我的查询作为基础。所以我要说我选择V2 + A3 + 2.接下来我想去找所有行的日期,其中var = V2,attr = A3,state = 2.接下来我需要仔细检查这些日期并计算所有日期其他var + attr +状态组合。例如,如果V2 + A3 + 2发生在01/01/14,02/06 / 14,02 / 07 / 14,04 / 09/14和05/03/14,它将通过这些上的所有其他变量日期并将每个var + attr +状态组合的出现次数相加。因此输出将对每个var + attr +状态组合进行分组,并且每个组合的计数都会显示。
要完成此操作,我使用的是查询:
SELECT m2.variable, m2.attr, m2.state, COUNT(*)
FROM mytable m1
JOIN mytable m2
ON m2.date = m1.date
WHERE (m1.variable, m1.attr, m1.state) = ('V2', 'A3', 2)
GROUP BY
m2.variable, m2.attr, m2.state
所以这个查询实际上返回了我选择的变量+属性+状态组合的计数。所以这只是一个组合,但我想得到可能组合的计数(~20,000个不同的变量x 5个不同的属性x 3个不同的状态)。我的初始方法是编写一个脚本来替换组合变量(例如( m1.variable,m1.attr,m1.state)=(SUB_VAR1,SUB_VAR2,SUB_VAR3))并简单地遍历所有组合并返回计数(我只对每个计数的最高20个计数感兴趣)。我想最初这可能需要几个小时才能完成。问题是查询非常非常慢,每个组合运行大约45秒。这里使用的表有大约15M - 20M行(~20,000个变量x5个属性x3个状态×60天),表格正在连接,因此要处理的行数很多,需要几个月的处理时间。我的主键是Variable + Attr + Date,当然还有一个索引。我曾尝试创建一个重复的表,但是使用MEMORY引擎希望它能加快进程,但它只会将速度提高大约5-10秒。我对查询性能不强,但我尝试了其他一些查询,但是他们没有帮助。我有需要,我想到一个更有效的查询,甚至可能完整的表重新设计?我已经尝试了各种似乎不起作用的东西,如何以高效的方式实现我需要的任何输入将非常感激。
答案 0 :(得分:0)
据我所知,您希望将查询基于所有组合。获取这些组合的日期,然后计算具有该日期的其他组合的数量..如果那是真的那么这将做你想要的。
SELECT Variable , Attr , COUNT(*) , State
FROM mytable
WHERE date IN
( SELECT date
FROM mytable
GROUP BY variable, attr, state
)
GROUP BY variable, attr, state
答案 1 :(得分:0)
使用cross join
生成所有组合,然后使用您的查询:
SELECT v.variable, a.attr, s.state, COUNT(m2.date)
FROM (select distinct variable from mytable) v cross join
(select distinct attr from mytable) a cross join
(select distinct state) from mytable) s left join
mytable m
on m.variable = v.variable and m.attr = a.attr and m.state = v.state left join
mytable m2
ON m2.date = m1.date and (m1.variable, m1.attr, m1.state) = ('V2', 'A3', 2)
GROUP BY v.variable, a.attr, s.state;
答案 2 :(得分:0)
你能否证实这给出了你期待的答案
select
bases.variable as basis_v,
bases.attr as basis_a,
bases.state as basis_s,
counts.variable,
counts.attr,
counts.state,
count(*) as count
from
mytable bases
inner join
mytable counts
on bases.date = counts.date
group by
bases.variable,
bases.attr,
bases.state,
counts.variable,
counts.attr,
counts.state
order by
bases.variable,
bases.attr,
bases.state,
counts.variable,
counts.attr,
counts.state;
另请注意,我未包含v, a, s
的所有组合,仅包括实际发生的组合。
由于自我加入,这仍然会相当慢,但至少你可以一次性获得所有结果。但是,请记住,它们可能高达20,000 x 20,000!