【问题标题】:how to use Union all query for fetching the records which is not in table?如何使用联合所有查询来获取不在表中的记录?
【发布时间】:2013-03-12 06:01:14
【问题描述】:

我在 MYSQL 数据库中有一个如下格式的_ad_display 表

╔═════════════╦═════════╦═════════╦═════════════════════╗
║ addisplayId ║ restId  ║ clicked ║     displaytime     ║
╠═════════════╬═════════╬═════════╬═════════════════════╣
║          1  ║  20707  ║      0  ║ 2013-03-07 10:50:55 ║
║          2  ║  20707  ║      1  ║ 2013-03-07 10:55:55 ║
║          3  ║  20711  ║      1  ║ 2013-03-08 12:50:55 ║
║          4  ║  20712  ║      1  ║ 2013-03-08 01:50:55 ║
║          5  ║  20707  ║      1  ║ 2013-03-08 10:50:55 ║
║          6  ║  20708  ║      1  ║ 2013-03-09 12:50:55 ║
║          7  ║  20707  ║      1  ║ 2013-03-09 09:50:55 ║
║          8  ║  20708  ║      0  ║ 2013-03-10 10:50:55 ║
║          9  ║  20708  ║      0  ║ 2013-03-11 11:50:55 ║
║         10  ║  20707  ║      0  ║ 2013-03-11 12:50:55 ║
╚═════════════╩═════════╩═════════╩═════════════════════╝

现在我想要的是用过去 7 天的数据获取 restId 的记录

如果当前日期是 2013-3-12 那么我想显示 2013-3-5 到 2013-3-11 的数据

     DISPLAY TIME                   CLICKED     count of row(impression)
March, 05 2013 00:00:00+0000            0       0             
March, 06 2013 00:00:00+0000            0       0
March, 07 2013 00:00:00+0000            1       2
March, 08 2013 00:00:00+0000            1       1
March, 09 2013 00:00:00+0000            1       1
March, 10 2013 00:00:00+0000            1       1
March, 11 2013 00:00:00+0000            0       1

我想忽略时间..只想在获取记录日期的同时关注日期 我想获取restId = 10707的记录,其中包含表中该日期的总行数和该日期的点击总和,如果表中没有上周日期出现的任何日期的记录,那么它应该打印该日期并在单击时打印 0,并且在行数列中打印 0。

我在 SQL fiddle 中制作了一个虚拟表并应用了此查询,但它不起作用..所以任何人都可以指导我...我知道它非常难以理解..但是如果您对我的问题有任何疑问..然后将清除你从你身边得到一个解决方案..

以下是我的查询,它没有提供正确的数据

select
  displaytime,
  sum(impression) as clicked,
  (count(impression) -1) as impressions
from (
  select
    displaytime,
    a_ad_display.clicked as impression
  from
    a_ad_display
  where
    a_ad_display.displaytime
  BETWEEN
    date_add(CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), interval -6 day)
    AND
    CONVERT_TZ(CURDATE( ),'+00:00','-11:00')
    and
    restId=10708
    group by
      a_ad_display.displaytime
    union distinct
    select
      CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), 0
    union distinct
    select
      date_add(CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), interval -1 day), 0
    union distinct
    select
      date_add(CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), interval -2 day), 0
    union distinct
    select
      date_add(CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), interval -3 day), 0
    union distinct
    select
      date_add(CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), interval -4 day), 0
    union distinct
    select
      date_add(CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), interval -5 day), 0
    union distinct
    select
      date_add(CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), interval -6 day), 0
) as x
group by
  date(displaytime)
order by
  displaytime

请忽略代码CONVERT_TZ(CURDATE( ),'+00:00','-11:00'),因为它只是将我的日期从UTC转换为用户时区...

这是我的 sql fiddle 链接 http://sqlfiddle.com/#!2/73f07/1

【问题讨论】:

    标签: mysql sql database


    【解决方案1】:

    此查询应显示正确的数据。不是一个非常“干净”的解决方案。如果你真的想包含没有数据的日期,你应该用日历表替换这些联合。

    SELECT IFNULL(z.displaytime, x.displaytime), IFNULL(z.clicked, 0), IFNULL(z.count, 0)  FROM
    
      (select
        date(CONVERT_TZ(CURDATE( ),'+00:00','-11:00')) AS 'displaytime', 0 AS 'Clicked', 0 AS 'count of row(impression)'
      union distinct
      select
        date(date_add(CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), interval -1 day)), 0, 0
      union distinct
      select
        date(date_add(CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), interval -2 day)), 0, 0
      union distinct
      select
        date(date_add(CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), interval -3 day)), 0, 0
      union distinct
      select
        date(date_add(CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), interval -4 day)), 0, 0
      union distinct
      select
        date(date_add(CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), interval -5 day)), 0, 0
      union distinct
      select
        date(date_add(CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), interval -6 day)), 0, 0) AS x
    
    LEFT JOIN
    
      (SELECT
        DATE(displaytime) AS 'displaytime',
        MAX(clicked) AS 'Clicked',
        COUNT(*) AS 'Count'
      FROM 
        a_ad_display
      WHERE (
        displaytime BETWEEN date_add(CURDATE(), interval -6 day) AND CURDATE()
      ) AND restId = 10707 
      GROUP BY DATE(displaytime)) AS z
    ON x.displaytime = z.displaytime
    

    【讨论】:

    • 感谢答案..它的工作。但为什么这不是一个干净的解决方案?
    【解决方案2】:

    可能有一种更清洁的方法,但这应该可以工作......

    select
      displaytime,
      sum(clicked) as clicked,
      sum(impressions) as impressions
    from (
    select
      displaytime,
      clicked,
      impressions
    from (
    select
      date(displaytime) as displaytime,
      sum(impression) as clicked,
      sum(legit) as impressions
    from (
      select
        displaytime,
        a_ad_display.clicked as impression,
      1 as legit
      from
        a_ad_display
      where
        a_ad_display.displaytime
      BETWEEN
        date_add(CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), interval -6 day)
        AND
        CONVERT_TZ(CURDATE( ),'+00:00','-11:00')
        and
        restId=10708
    ) as x
    group by
      date(displaytime)
    ) y
    union distinct
        select
          date(CONVERT_TZ(CURDATE( ),'+00:00','-11:00')), 0, 0
        union distinct
        select
          date(date_add(CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), interval -1 day)), 0, 0
        union distinct
        select
          date(date_add(CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), interval -2 day)), 0, 0
        union distinct
        select
          date(date_add(CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), interval -3 day)), 0, 0
        union distinct
        select
          date(date_add(CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), interval -4 day)), 0, 0
        union distinct
        select
          date(date_add(CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), interval -5 day)), 0, 0
        union distinct
        select
          date(date_add(CONVERT_TZ(CURDATE( ),'+00:00','-11:00'), interval -6 day)), 0, 0
    ) z
    group by
      displaytime
    order by
      displaytime
    

    【讨论】:

      【解决方案3】:

      restID 20707 的其他一些解决方案。对于 2013-03-10,restID 20707 没有记录。

      查询SQLFIDDLEExample

      SELECT d.Date,
      (SELECT CASE WHEN COUNT(clicked) >0 THEN 1 ELSE 0 END
      FROM a_ad_display
      WHERE DATE(displaytime) = d.Date 
      AND clicked = 1
      AND restId  = 20707  ) Clicked,
      (SELECT COUNT(*)
      FROM a_ad_display
      WHERE DATE(displaytime) = d.Date 
      AND restId  = 20707  ) 'count of row'
      FROM 
      (SELECT a.Date
      FROM
        (SELECT curdate() - INTERVAL (a.a + (10 * b.a) + (100 * c.a)) DAY AS Date
         FROM
           (SELECT 0 AS a
            UNION ALL SELECT 1
            UNION ALL SELECT 2
            UNION ALL SELECT 3
            UNION ALL SELECT 4
            UNION ALL SELECT 5
            UNION ALL SELECT 6
            UNION ALL SELECT 7
            UNION ALL SELECT 8
            UNION ALL SELECT 9) AS a CROSS
         JOIN
           (SELECT 0 AS a
            UNION ALL SELECT 1
            UNION ALL SELECT 2
            UNION ALL SELECT 3
            UNION ALL SELECT 4
            UNION ALL SELECT 5
            UNION ALL SELECT 6
            UNION ALL SELECT 7
            UNION ALL SELECT 8
            UNION ALL SELECT 9) AS b CROSS
         JOIN
           (SELECT 0 AS a
            UNION ALL SELECT 1
            UNION ALL SELECT 2
            UNION ALL SELECT 3
            UNION ALL SELECT 4
            UNION ALL SELECT 5
            UNION ALL SELECT 6
            UNION ALL SELECT 7
            UNION ALL SELECT 8
            UNION ALL SELECT 9) AS c) a
      where a.Date >= '2013-01-01' and a.Date < curdate()) d
      WHERE d.Date >= date_add(curdate(), INTERVAL -7 DAY)
      ORDER BY d.Date
      

      结果:

      |                         DATE | CLICKED | COUNT OF ROW |
      ---------------------------------------------------------
      | March, 05 2013 00:00:00+0000 |       0 |            0 |
      | March, 06 2013 00:00:00+0000 |       0 |            0 |
      | March, 07 2013 00:00:00+0000 |       1 |            2 |
      | March, 08 2013 00:00:00+0000 |       1 |            1 |
      | March, 09 2013 00:00:00+0000 |       1 |            1 |
      | March, 10 2013 00:00:00+0000 |       0 |            0 |
      | March, 11 2013 00:00:00+0000 |       0 |            1 |
      

      【讨论】:

        【解决方案4】:

        看看这个问题:

        这和你正在做的几乎一模一样

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2020-04-01
          • 1970-01-01
          • 1970-01-01
          • 2017-09-30
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多