mysql - 用子查询重写查询

时间:2014-01-23 10:23:29

标签: mysql sql

考虑一个表具有列Id,Name,Surname的用户和具有列Ip和Actor的表Actions。我需要为每个IP检索使用该IP执行操作的用户集。 我现在看起来像:

SELECT a.ip, (
    SELECT GROUP_CONCAT(t.id, '-', t.name, ' ', t.surname) FROM(
        SELECT ud.id, ud.name, ud.surname
    FROM users_data AS ud
    JOIN actions AS a2 ON a2.actor = ud.id
    WHERE a2.ip = a.ip
    GROUP BY ud.id) AS t
    )
    FROM actions AS a
WHERE a.ip != '' AND a.ip != '0.0.0.0'
GROUP BY a.ip

它不起作用,因为内部子查询中的where子句中的a.ip未知。

对性能问题,我需要避免使用DISTINCT。

有什么建议吗?

3 个答案:

答案 0 :(得分:1)

您可以将查询重写为

SELECT n.ip, GROUP_CONCAT( DISTINCT n.your_user SEPARATOR ' -- ') `users` FROM
(  
    SELECT a.ip  AS ip, CONCAT(t.id, '-', t.name, ' ', t.surname) `your_user`
    FROM users_data AS ud
    JOIN actions AS a ON a.actor = ud.id         
) `new_table` n
WHERE n.ip != '' AND n.ip != '0.0.0.0'
GROUP BY n.ip
  

注意请注意,结果会被截断为最大长度   这是由group_concat_max_len系统变量给出的   默认值为1024

答案 1 :(得分:0)

您是否尝试在子查询外编写条件a2.ip = a.ip? 即在外部查询的where子句中!

答案 2 :(得分:0)

我使用这个查询解决了它(仍然很慢,所以还有改进的空间......):

SELECT SQL_NO_CACHE t.ip, COUNT(t.id) AS c, GROUP_CONCAT(t.id, '-', t.name, ' ',   t.surname, '-', t.designerAt > 0) FROM ( 
    SELECT a.ip, ud.id, ud.name, ud.surname, u.designerAt
    FROM actions AS a
    JOIN users_data AS ud ON ud.id = a.actor
    JOIN users AS u ON u.id = a.actor
    WHERE a.ip !=  ''
    AND a.ip !=  '0.0.0.0'
    AND a.actor !=0
    GROUP BY a.ip, a.actor
    ) AS t
GROUP BY t.ip