优化复杂的MySQL选择报告

时间:2011-04-11 19:17:10

标签: mysql sql database-design relational-database subquery

我正在构建一个应用程序,

a)每个图书管理员都可以创建一个活动 b)作为该活动的一部分执行的操作在campaign_actions中被跟踪,操作是页面加载

为了报告每个广告系列中的操作数量,I wrote this SQL query (for MySQL)针对以下数据库结构进行报告,目的是跟踪图书管理员针对每个广告系列采取的操作数量:

LIBRARIANS
id | status

CAMPAIGNS
id | librarian_id

CAMPAIGN_ACTIONS
id | campaign_id | name

我遇到的问题是:

a)我必须在相关的子选择中指定我想要计数的字段 b)因此查询将非常昂贵

我的问题是,由于广告系列有多种操作,如何以更有效的方式有效计算 广告系列

>

不太复杂的查询相当于返回结果集:

  librarians.id   |  librarians.status  |  campaign_actions.name
       1                    3                     pageX
       1                    3                     pageY
       1                    3                     pageZ
       1                    3                     pageA
       1                    3                     pageB
       2                    3                     pageX    

这意味着我必须逐行解析应用程序代码中的结果集,这可能更多昂贵。

我感谢您对此问题的任何想法。

2 个答案:

答案 0 :(得分:1)

将任务分解为较小的任务(视图):

--- campaings per librarian
CREATE VIEW count_librarian_campaigns
AS ( SELECT lib.id AS lib_id
          , COUNT(c.id)
                   AS num_campaigns
     FROM librarians lib
     LEFT JOIN campaigns c
       ON c.librarian_id = lib.id
     GROUP BY lib.id
   )

--- campaign actions per campaign
CREATE VIEW count_campaign_actions
AS ( SELECT c.id   AS c_id
          , COUNT(ca.campaign_id)
                   AS num_actions
     FROM campaigns c
     LEFT JOIN campaign_actions ca
       ON ca.campaign_id = c.id
     GROUP BY c.id
   )

所以,你可以这样查询:

SELECT lib.id AS lib_id
     , countlibc.num_campaigns
     , c.id   AS c_id 
     , countca.num_actions
FROM librarians lib
JOIN count_librarian_campaigns countlibc
  ON countlibc.lib_id = lib.id
LEFT JOIN campaigns c
  ON c.librarian_id = lib.id
JOIN count_campaign_actions countca
  ON countca.c_id = c.id

答案 1 :(得分:0)

这样的事情是否适用于您的目的?

SELECT librarians_id,COUNT(librarians_id) FROM (
    SELECT librarians.id as librarians_id,
            librarians.status as librarians_status,
            campaign_actions.name as campaign_actions_name
    FROM campaign_actions
    INNER JOIN campaigns
           ON campaign_actions.campaign_id = campaigns.id
    INNER JOIN librarians
           ON campaigns.librarian_id = librarians.id
    GROUP BY campaign_actions.name,librarians.id,librarians.status ) as a

也许我误解了你的想法。内部查询似乎会返回您在上面表示的表。