【问题标题】:MySQL join tables with subqueryMySQL 使用子查询连接表
【发布时间】:2015-09-26 16:14:35
【问题描述】:

我在下面有这个疯狂的查询。我想组织它们,但不知道如何。 有人可以帮我运行这个查询吗?我想加入下面的 5 个子查询表,最后,结果将是一个显示 line item_id 的表,其中包含 last5days、last10days、last30days、last60days、last90days。 非常感谢!

Select q1.line_item_id, 
       q1.domains as 'last5days', 
       q2.domains as 'last10days', 
       q3.domains as 'last30days', 
       q4.dpmains as 'last60days', 
       q5.domains as 'last90days'
From q1
Join q2 on q1.line_item_id = q2.line_item_id
Join q3 on q1.line_item_id = q3.line_item_id
Join q4 on q1.line_item_id = q4.line_item_id
Join q4 on q1.line_item_id = q5.line_item_id


select q1.line_item_id, count(*) domains
from (
      select distinct line_item_id, domain
      from rpt_domain_by_campaign
      where event_date between DATE_SUB(curdate(), INTERVAL 5 DAY) 
      and now()
      ) q1
group by q1.line_item_id


select q1.line_item_id, count(*) domains
from (
      select distinct line_item_id, domain
      from rpt_domain_by_campaign
      where event_date between DATE_SUB(curdate(), INTERVAL 10 DAY) 
      and now()
      ) q2
group by q1.line_item_id


select q1.line_item_id, count(*) domains
from (
      select distinct line_item_id, domain
      from rpt_domain_by_campaign
      where event_date between DATE_SUB(curdate(), INTERVAL 30 DAY) 
      and now()
      ) q3
group by q1.line_item_id


select q1.line_item_id, count(*) domains
from (
      select distinct line_item_id, domain
      from rpt_domain_by_campaign
      where event_date between DATE_SUB(curdate(), INTERVAL 60 DAY) 
      and now()
      ) q4
group by q1.line_item_id


select q1.line_item_id, count(*) domains
from (
      select distinct line_item_id, domain
      from rpt_domain_by_campaign
      where event_date between DATE_SUB(curdate(), INTERVAL 90 DAY) 
      and now()
      ) q5
group by q1.line_item_id

【问题讨论】:

    标签: mysql loops date while-loop stack


    【解决方案1】:

    只使用按最大日期分组 select line_item_id, Sum( CASE WHEN DATEDIFF(curdate(), event_date) <= 5 then 1 ELSE 0 END ) 'last5days', Sum( CASE WHEN DATEDIFF(curdate(), event_date) <= 10 then 1 ELSE 0 END ) 'last10days', Sum( CASE WHEN DATEDIFF(curdate(), event_date) <= 30 then 1 ELSE 0 END ) 'last30days', Sum( CASE WHEN DATEDIFF(curdate(), event_date) <= 60 then 1 ELSE 0 END ) 'last60days', Sum( CASE WHEN DATEDIFF(curdate(), event_date) <= 90 then 1 ELSE 0 END ) 'last90days' from ( select line_item_id, max(event_date) event_date from rpt_domain_by_campaign where event_date < curdate() group by line_item_id, domain ) a Group by line_item_id

    【讨论】:

      【解决方案2】:

      我建议使用count(distinct...) 来避免每个子查询中的额外嵌套层。

      我还建议切换子查询的顺序并使用外连接,因为并非过去 90 天内有行的每个行项目也会在过去 60 天内有行,等等。

      试试这样的:

      Select q1.line_item_id, 
             q1.domains as last90days, 
             coalesce(q2.domains,0) as last60days, 
             coalesce(q3.domains,0) as last30days, 
             coalesce(q4.domains,0) as last10days, 
             coalesce(q5.domains,0) as last5days
      from 
      (
        select line_item_id, count(distinct domain) as domains
        from rpt_domain_by_campaign
        where event_date between DATE_SUB(curdate(), INTERVAL 90 DAY) 
        and now()
        group by line_item_id
      ) q1 
      left outer join
      (
        select line_item_id, count(distinct domain) as domains
        from rpt_domain_by_campaign
        where event_date between DATE_SUB(curdate(), INTERVAL 60 DAY) 
        and now()
        group by line_item_id
      ) q2 on q1.line_item_id = q2.line_item_id
      left outer join
      (
        select line_item_id, count(distinct domain) as domains
        from rpt_domain_by_campaign
        where event_date between DATE_SUB(curdate(), INTERVAL 30 DAY) 
        and now()
        group by line_item_id
      ) q3 on q1.line_item_id = q3.line_item_id
      left outer join
      (
        select line_item_id, count(distinct domain) as domains
        from rpt_domain_by_campaign
        where event_date between DATE_SUB(curdate(), INTERVAL 10 DAY) 
        and now()
        group by line_item_id
      ) q4 on q1.line_item_id = q4.line_item_id
      left outer join
      (
        select line_item_id, count(distinct domain) as domains
        from rpt_domain_by_campaign
        where event_date between DATE_SUB(curdate(), INTERVAL 5 DAY) 
        and now()
        group by line_item_id
      ) q5 on q1.line_item_id = q5.line_item_id
      

      【讨论】:

        【解决方案3】:

        只需使用 sum 和 case 就更容易了: select line_item_id, Sum( CASE WHEN DATEDIFF(curdate(), event_date) <= 5 then 1 ELSE 0 END ) 'last5days', Sum( CASE WHEN DATEDIFF(curdate(), event_date) <= 10 then 1 ELSE 0 END ) 'last10days', Sum( CASE WHEN DATEDIFF(curdate(), event_date) <= 30 then 1 ELSE 0 END ) 'last30days', Sum( CASE WHEN DATEDIFF(curdate(), event_date) <= 60 then 1 ELSE 0 END ) 'last60days', Sum( CASE WHEN DATEDIFF(curdate(), event_date) <= 90 then 1 ELSE 0 END ) 'last90days' from rpt_domain_by_campaign Group by line_item_id

        【讨论】:

        • 如果某些 event_date 记录在未来,您需要在 WHEN 中添加另一个条件,例如 WHEN DATEDIFF(curdate(), event_date) > 0 AND DATEDIFF(curdate(), event_date)
        • select ... from (select line_item_id, min(event_date) event_date from rpt_domain_by_campaign where event_date >= curdate() group by line_item_id, domain) a Group by line_item_id
        猜你喜欢
        • 1970-01-01
        • 2011-11-25
        • 1970-01-01
        • 2010-11-06
        • 2021-02-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多