我尝试从特定类型中获取最多类型的Entrie。为了说清楚,我将从示例开始。我的列类型实际上是外键。
示例:
我的计数器表(约1.500.000行),它计算所有在不同交通信号灯下看到的汽车:
id, datetime, type, traffic_light_id
0, '09:59', 'red ford', 2
1, '10:00', 'black bmw', 1
2, '10:11', 'red ford', 1
3, '10:30', 'yellow ford', 1
4, '11:01', 'black bmw', 1
5, '11:09', 'red ford', 1
6, '11:18', 'green mercedes', 1
7, '11:20', 'black bmw', 2
8, '11:44', 'white renault', 2
9, '11:44', 'red renault', 1
我在每列上都有一个索引。 id是主键。
需要:
所以我想得到的是“black bmw”的结果,其中traffic_light_id = 1。 结果应该总结所有的bevore和'black bmw'之后看到的汽车类型。
结果应为:
count, type, traffic_light_id
2, 'red ford', 1
1, 'yellow ford', 1
我的糟糕解决方案:
所以直到现在我的解决办法是在计数器中迭代所有计数,其中type ='black bmw'和traffic_light_id = 1.
对于每个计数,我得到了bevore,并且在我的php脚本中也看到了带有traffic_light_id的元素(每个计数还有两个查询)。
之后我按照我的阵列中给定的汽车类型对结果进行分组并计算其频率。
对于类似的东西,有没有更好的解决方案?最好的事情只是一个SQL查询!
答案 0 :(得分:2)
我首先明白你想要一个简单的小组:
select type, count(*) as totalseen,
sum(case when traffic_light_id = 1 then 1 else 0 end) as SeenTrafficLight1
from t
group by type
如果你真的只想要交通灯= 1,那么使用where
子句:
select type, traffic_light_id, count(*)
from t
where traffic_light_id = 1
group by type
Bort,谢谢你的澄清。这使问题更加有趣。
以下是我们使用相关子查询的方法。以下是此类型的示例:
select typeBefore, count(*)
from (select t.*,
(select type from t t2 where t2.datetime < t.datetime order by t2.datetime desc limit 1
) as typeBefore,
(select type from t t2 where t2.datetime > t.datetime order by t2.datetime limit 1
) as typeAfter
from t
) t
where type = 'black,bmw' and traffic_light_id = 1
group by typeBefore
子查询使用datetime来确定之前的版本。如果id
是主键并以相同方式排序,则可以使用它。
然后这个过程有点复杂。这是通过交叉连接到具有两行的表来实现它的一种方法。这样就可以同时对typeBefore
和typeAfter
进行分组:
select (case when which = 'Before' then typeBefore else typeAfter end), count(*)
from (select t.*,
(select type from t t2 where t2.datetime < t.datetime order by t2.datetime desc limit 1
) as typeBefore,
(select type from t t2 where t2.datetime > t.datetime order by t2.datetime limit 1
) as typeAfter
from t
) t cross join
(select 'before' as which union all select 'after') const
where type = 'black,bmw' and traffic_light_id = 1
group by (case when which = 'Before' then typeBefore else typeAfter end)