进行子选择和分组

时间:2012-12-25 16:29:48

标签: mysql subquery

我有两张桌子:

main:id_main,field1,filter

main_logs(5000万行):auto inc,id_main,path

我在寻找以下结果: id_main,field1,最常见的路径

我尝试了以下查询:

select id_main, 
  field1, 
  (select path, count(*) as cpt 
   from main_log 
   where main_log.id_main=main.id_main group by path order by cpt desc limit 1) 
from main 
where filter in (1,3,5);

Mysql返回:操作数应包含1列

如果我删除路径,结果是正确的,但我错过了路径值。

select id_main, 
  field1, 
  (select path, count(*) as cpt 
   from main_log 
   where main_log.id_main=main.id_main group by path order by cpt desc limit 1) 
from main 
where filter in (1,3,5);

我不需要count(*)的结果,但我需要它为“order by”

如何编写此查询以获取结果? 感谢

主要

id_main     | field1    | filter
1       | red       | 1
2       | blue      | 3
3       | pink      | 1

main_logs

autoinc     | id_main   | path
1       | 1         | home1
2       | 1         | home2
3       | 1         | home2
4       | 2         | house2
5       | 2         | house7
6       | 2         | house7
7       | 3         | casee

预期结果

id_main     | fields1   | most common path
1       | red       | home2
2       | blue      | house7
3       | pink      | casee

4 个答案:

答案 0 :(得分:2)

试试这个:

SELECT m.id_main, m.field1, A.path 
FROM main m 
INNER JOIN (SELECT * 
            FROM (SELECT id_main, path, COUNT(*) cnt
                  FROM main_log ml  
                  WHERE EXISTS (SELECT * FROM main m WHERE ml.id_main = m.id_main AND filter IN (1,3,5))
                  GROUP BY id_main, path 
                  ORDER BY cnt DESC
                  ) AS A 
            GROUP BY id_main
            ) AS A ON m.id_main = A.id_main;

OLD CODE IGNORE

SELECT m.id_main, m.field1, A.path 
FROM main m 
INNER JOIN (SELECT * FROM (SELECT id_main, path, count(*) cnt
            FROM main_log 
            GROUP BY id_main, path 
            ORDER BY cnt DESC) GROUP BY id_main) as A on m.id_main = A.id_main 
WHERE filter IN (1,3,5);

答案 1 :(得分:2)

您需要使用:

SELECT id_main, field, 
    (SELECT path 
    FROM main_logs 
    WHERE id_main=main.id_main 
    GROUP BY path 
    ORDER BY count(path) DESC 
    LIMIT 1) AS most 
FROM main 
WHERE filter IN (1,3,5);

经过测试,它正在运作。

答案 2 :(得分:0)

您在子查询中返回两列。你只需要退回一个。

示例数据:

ID_MAIN     FIELD1  FILTER
1   h   1
2   x   2
3   y   3


AUTOINC     ID_MAIN     PATH
11  1   abc
12  2   abd
13  1   xyz
14  1   ghf
15  2   xyz

尝试退出:SQLFIDDLE

查询:

select id_main, 
  field1, 
  (select count(id_main) as cpt 
   from main_logs 
   where main_logs.id_main=main.id_main 
   group by path 
   order by cpt desc limit 1) as CPTs
from main 
where filter in (1,3,5);

结果:

ID_MAIN     FIELD1  CPTs
1       h   1
3       y   (null)

编辑以提供每个ID的每个路径的最大计数

绝对不是最优雅的查询。太可能加入和子查询可能导致相当荒谬的性能下滑。

关注您的示例数据,但表main,id = 3,粉红色过滤器= 5除外。因此,它符合您的filter条件。然而,即使没有那个批评,以下查询似乎也适用于逻辑。

查询:

select a.id, b.path, a.mx
from
(select x.id, x.path, max(x.ct) as mx
from (
select m.id_main as id, ml.path, 
count(ml.id_main) as ct
from main m
left join 
main_logs ml
on ml.id_main = m.id_main
group by ml.path) as x
group by x.id) as a
inner join 
(select m.id_main as id, m.filter, ml.path, 
count(ml.id_main) as ct
from main m
left join 
main_logs ml
on ml.id_main = m.id_main
group by ml.path) as b
on a.id = b.id
and a.mx = b.ct
where b.filter in (1,2,3)
order by a.mx desc
;

结果:

ID  PATH    MX
1   home2   2
2   house7  2
3   casee   1

答案 3 :(得分:0)

SELECT 
    m.id_main,
    m.field1,
    ml.path,
    IFNULL(ml.Count,0)
FROM main as m
LEFT JOIN (
           SELECT
                 id_main, 
                 path,
                 COUNT(path) as Count
           FROM main_logs
           GROUP BY id_main
          ) as ml on ml.id_main = m.id_main