【问题标题】:multiple nested SELECT query's and sum two columns多个嵌套的 SELECT 查询并对两列求和
【发布时间】:2017-10-06 21:58:45
【问题描述】:

我有一个 mysql 表,我试图在其上运行单个/嵌套查询。

SELECT 
`subscriber_id`, 
(SELECT...?) AS total_campaigns, 
(SELECT...?) AS total_opens,
(total_opens / total_campaigns) as percentage
FROM
`campaigns_table`

type 列的值 = 2 表示活动已打开。

我希望返回一个包含所有 subscriber_id 的结果集,其中包含总广告系列和总打开次数


查询结果数据

+---------------+-----------------+-------------+------------+
| subscriber_id | total_campaigns | total_opens | percentage |
+---------------+-----------------+-------------+------------+
|             1 |               2 |           1 |        0.5 |
|             2 |               2 |           2 |        1.0 |
|             3 |               2 |           0 |        0.0 |
|             4 |               1 |           0 |        0.0 |
|             5 |               1 |           1 |        1.0 |
+---------------+-----------------+-------------+------------+

subscriber_id 1 将是 total_campaigns = 2(campaign_id 的 37428,37239)和total_opens = 1(只有campaign_id 27428 具有类型 2 记录)


示例表数据

+---------------+-------------+------------+-------+------+---------+ | subscriber_id | campaign_id | timestamp | count | type | link_id | +---------------+-------------+------------+-------+------+---------+ | 1 | 37428 | 1434513738 | 1 | 1 | 0 | | 1 | 37428 | 1434513758 | 1 | 1 | 0 | | 1 | 37428 | 1434513338 | 2 | 2 | 0 | | 1 | 37429 | 1434511738 | 1 | 1 | 0 | | 1 | 37429 | 1434311738 | 1 | 1 | 1 | | 2 | 37428 | 1534513738 | 1 | 1 | 0 | | 2 | 37428 | 1534513758 | 1 | 1 | 0 | | 2 | 37428 | 1534513338 | 2 | 2 | 0 | | 2 | 37429 | 1534511738 | 1 | 1 | 1 | | 2 | 37429 | 1534311738 | 1 | 2 | 0 | | 3 | 37428 | 1534513738 | 1 | 1 | 0 | | 3 | 37429 | 1534511738 | 1 | 1 | 1 | | 4 | 57428 | 1534513738 | 1 | 1 | 0 | | 4 | 57428 | 1534513758 | 1 | 1 | 0 | | 5 | 57428 | 1534513338 | 3 | 2 | 0 | +---------------+-------------+------------+-------+------+---------+


使用下面@spencer7593 的答案。然后如何使用结果更新另一个表?

尝试做这样的事情(我的方法不行)

    UPDATE `subscribers` a
    LEFT JOIN `campaigns_table` b ON a.`ID` = b.`subscriber_id`
    SET a.`STATUS` = 2
    FROM(
        SELECT t.subscriber_id
             , COUNT(DISTINCT t.campaign_id)                   AS total_campaigns
             , COUNT(DISTINCT IF(t.type=2,t.campaign_id,NULL)) AS open_campaigns
             , COUNT(DISTINCT IF(t.type=2,t.campaign_id,NULL))
             / COUNT(DISTINCT t.campaign_id)                   AS percentage
        FROM `campaigns_table` t
        GROUP BY t.subscriber_id  
        HAVING COUNT(DISTINCT t.campaign_id) > 5 AND COUNT(DISTINCT IF(t.type=2,t.campaign_id,NULL)) = 0
        ORDER BY t.subscriber_id
    ) i

【问题讨论】:

  • total_campaigns 和 total_opens 的查询是什么?您不能使用 total_campaigns 和 total_opens 作为您编写的百分比,因为这些列不在表campaigns_table中
  • 正确。 total_campaigns 和 total_opens 不是有效的列。我只是用它作为我尝试做的一个例子。

标签: mysql sql database


【解决方案1】:

在我看来,这是一个可以通过条件聚合解决的问题,只需通过表一次,无需任何嵌套查询。

SELECT t.subscriber_id
     , COUNT(DISTINCT t.campaign_id)                   AS total_campaigns
     , COUNT(DISTINCT IF(t.type=2,t.campaign_id,NULL)) AS open_campaigns
     , COUNT(DISTINCT IF(t.type=2,t.campaign_id,NULL))
     / COUNT(DISTINCT t.campaign_id)                   AS percentage
  FROM `campaigns_table` t
 GROUP BY t.subscriber_id  
 ORDER BY t.subscriber_id

可以使用嵌套查询生成等效结果,但一般来说,单次遍历表(使用单次 SELECT)将具有更有效的访问计划。

如果需要使用嵌套查询(我不明白为什么会有),一般来说,我更喜欢在 SELECT 列表中使用内联视图而不是相关查询。

SELECT q.subscriber_id
     , SUM(1)                       AS total_campaigns
     , SUM(q.open_campaign)         AS open_campaigns
     , SUM(q.open_campaign)/SUM(1)  AS percentage
  FROM ( SELECT t.subscriber_id
              , t.campaign
              , MAX(t.type=2) AS `open_campaign`
           FROM `campaigns_table` t
          WHERE t.campaign IS NOT NULL
          GROUP
             BY t.subscriber_id
              , t.campaign
       ) q
 ORDER BY q.subscriber

如果我们想在 SELECT 列表中使用嵌套查询,那些将是相关子查询...

SELECT s.subscriber
     , (      SELECT COUNT(DISTINCT t.campaign) 
                FROM `campaigns_table` t
               WHERE t.subscriber = s.subscriber
       ) AS total_campaigns

     , (      SELECT COUNT(DISTINCT o.campaign) 
                FROM `campaigns_table` o
               WHERE o.subscriber = s.subscriber
                 AND o.type=2
       ) AS open_campaigns

     , (      SELECT COUNT(DISTINCT po.campaign)
                FROM `campaigns_table` po
               WHERE po.subscriber = s.subscriber
                 AND po.type=2
       )
     / (      SELECT COUNT(DISTINCT pt.campaign) 
                FROM `campaigns_table` pt
                WHERE pt.subscriber = s.subscriber
       ) AS percentage

  FROM ( SELECT r.subscriber
           FROM `campaigns_table` r
         GROUP BY r.subscriber
       ) s
 ORDER BY s.subscriber

【讨论】:

  • 如何使用结果更新另一个表?我需要找到每个subscriber_id,有一个open_campaigns = 0,然后在另一个表中设置statussubscribers)。
猜你喜欢
  • 1970-01-01
  • 2011-09-27
  • 2019-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多