整合MySQL查询

时间:2014-08-19 06:58:50

标签: php mysql sql mysqli

我想知道我使用的4个查询如何合并到一个查询中。我能够查询数据集中表示的所有日期以及每个特定日期的点击次数。理想情况下,我也可以从该查询中获得安装次数(每天),总费用(每天)和备注(每天)。

我已经考虑过如何实现这一点,但由于我是MySQL的新手,因此没有提出任何完整的解决方案。有没有一种从多个表中提取数据的好方法?

$days = mysqli_query($link, "
    SELECT
      t1.date,
      t1.clicks
    FROM (SELECT
        date_format(date_sub(ic.click_utc, INTERVAL 7 HOUR), '%Y-%m-%d') as date,
        count(distinct ic.txid) as clicks
          FROM users_clicks ic
          GROUP BY date_format(date_sub(click_utc, INTERVAL 7 HOUR), '%Y-%m-%d')
          ORDER BY date DESC) t1
    WHERE date >= '2014-06-28'");
while ($day = mysqli_fetch_assoc($days)) {
    $date = $day['date'];
    $day_clicks = $day['clicks'];
    $day_installs = mysqli_fetch_row(mysqli_query($link, sprintf("SELECT count(txid) FROM (SELECT txid FROM users_installs WHERE date_format(date_sub(click_utc, INTERVAL 7 HOUR), '%%Y-%%m-%%d') = '%s' GROUP BY txid) table1", $day['date'])));
    $day_cost = mysqli_fetch_row(mysqli_query($link, sprintf("SELECT sum(earnings) FROM (SELECT max(cost) as earnings FROM users_clicks WHERE date_format(date_sub(click_utc, INTERVAL 7 HOUR), '%%Y-%%m-%%d') = '%s' GROUP BY txid) table1", $day['date'])));
    $note = mysqli_fetch_assoc(mysqli_query($link, sprintf("SELECT * FROM reporting_notes WHERE date_format(date_sub(timestamp, INTERVAL 7 HOUR), '%%Y-%%m-%%d') = '%s' LIMIT 1", $day['date'])));
}

以下是表格的结构:

Users_clicks:

   txid  |       click_utc        |  cost  
   12t3  |   2014-08-19 07:08:47  |  0.50
   27a5  |   2014-08-18 03:28:03  |  0.25
   48a5  |   2014-08-17 12:55:23  |  0.25

Users_installs:

   txid  |       click_utc 
   1o23  |   2014-08-19 07:08:47
   1ee3  |   2014-08-17 11:10:53

Reporting_notes:

      timestamp        |  note  
  2014-08-19 07:08:47  |  "hey"
  2014-08-17 03:02:41  |  "hey"

所需的输出:点击次数,安装次数,总费用以及数据集中每个日期的任何备注

2 个答案:

答案 0 :(得分:2)

首先:MySQL能够处理命名的时区,但您需要首先在时区上填充信息表。请参阅CONVERT_TZ的文档作为起点。

由于您的表似乎不相关(即没有包含所有txid的主表,...),您可能最好使用接近于触发单独查询的子查询开始。

点击次数和每日费用:

SELECT
  DATE(CONVERT_TZ(click_utc, '+00:00', '-07:00')) AS date,
  COUNT(*)                                        AS clicks,
  SUM(cost)                                       AS costs
FROM users_clicks
GROUP BY DATE(CONVERT_TZ(click_utc, '+00:00', '-07:00'));
只计算每个txid一次
SELECT
  DATE(CONVERT_TZ(min_click_utc, '+00:00', '-07:00')) AS date,
  COUNT(*)                                            AS clicks,
  SUM(max_costs)                                      AS costs
FROM (SELECT
        txid,
        MIN(click_utc) AS min_click_utc,
        MAX(cost)      AS max_costs
      FROM users_clicks
      GROUP BY txid) distinct_txids
GROUP BY DATE(CONVERT_TZ(min_click_utc, '+00:00', '-07:00'))

每天安装:

SELECT
  DATE(CONVERT_TZ(click_utc, '+00:00', '-07:00')) AS date,
  COUNT(*)                                        AS installs
FROM users_installs
GROUP BY DATE(CONVERT_TZ(click_utc, '+00:00', '-07:00'));
只计算每个txid一次
SELECT
  DATE(CONVERT_TZ(min_click_utc, '+00:00', '-07:00')) AS date,
  COUNT(*)                                            AS installs
FROM (SELECT
        txid,
        MIN(click_utc) AS min_click_utc
      FROM users_installs
      GROUP BY txid) distinct_txids
GROUP BY DATE(CONVERT_TZ(min_click_utc, '+00:00', '-07:00'));
每天

备注

(请注意,GROUP_CONCAT默认只返回1024个字符。可以通过将group_concat_max_len设置为更高的值来更改:

SELECT
  DATE(CONVERT_TZ(timestamp, '+00:00', '-07:00')) AS date,
  COUNT(*)                                        AS note_count,
  GROUP_CONCAT(note SEPARATOR ', ')               AS notes
FROM reporting_notes
GROUP BY DATE(CONVERT_TZ(timestamp, '+00:00', '-07:00'));

如果您想立即获取所有内容,您需要先获得一个共同的日期池,因为MySQL只有LEFTRIGHT OUTER JOIN s,而不是FULL OUTER JOIN s:

SELECT DISTINCT
  date
FROM (
       SELECT
         DATE(CONVERT_TZ(click_utc, '+00:00', '-07:00')) AS date
       FROM users_clicks
       UNION SELECT
               DATE(CONVERT_TZ(click_utc, '+00:00', '-07:00')) AS date
             FROM users_installs
       UNION SELECT
               DATE(CONVERT_TZ(timestamp, '+00:00', '-07:00')) AS date
             FROM reporting_notes) dates;

然后你可以将它们全部合并到

一个查询

SELECT
  dates.date,
  clicks.clicks,
  clicks.costs,
  installs.installs,
  notes.note_count,
  notes.notes
FROM (SELECT DISTINCT
        date
      FROM (
             SELECT
               DATE(CONVERT_TZ(click_utc, '+00:00', '-07:00')) AS date
             FROM users_clicks
             UNION SELECT
                     DATE(CONVERT_TZ(click_utc, '+00:00', '-07:00')) AS date
                   FROM users_installs
             UNION SELECT
                     DATE(CONVERT_TZ(timestamp, '+00:00', '-07:00')) AS date
                   FROM reporting_notes) data) dates
  LEFT JOIN (SELECT
               DATE(CONVERT_TZ(click_utc, '+00:00', '-07:00')) AS date,
               COUNT(*)                                        AS clicks,
               SUM(cost)                                       AS costs
             FROM users_clicks
             GROUP BY DATE(CONVERT_TZ(click_utc, '+00:00', '-07:00'))) clicks ON clicks.date = dates.date
  LEFT JOIN (SELECT
               DATE(CONVERT_TZ(click_utc, '+00:00', '-07:00')) AS date,
               COUNT(*)                                        AS installs
             FROM users_installs
             GROUP BY DATE(CONVERT_TZ(click_utc, '+00:00', '-07:00'))) installs ON installs.date = dates.date
  LEFT JOIN (SELECT
               DATE(CONVERT_TZ(timestamp, '+00:00', '-07:00')) AS date,
               COUNT(*)                                        AS note_count,
               GROUP_CONCAT(note SEPARATOR ', ')               AS notes
             FROM reporting_notes
             GROUP BY DATE(CONVERT_TZ(timestamp, '+00:00', '-07:00'))) notes ON notes.date = dates.date;

如果您知道,在安装发生的每一天,还有一个点击,您可以使用点击查询作为日期池,查询会变得更容易。无论如何,我可能会运行一个单独的查询来获取每天的注释,以便能够对文本采取行动。

仅计算一次txids

此查询将确保users_installs和users_clicks中的每个txid仅在其发生的最早日期计数一次。由于有两个额外的子子查询,性能将(至少)略差。如果txids已经不同,我会建议不要这样做。如果您开始在子查询中过滤日期,则可以提高性能。

SELECT
  dates.date,
  clicks.clicks,
  clicks.costs,
  installs.installs,
  notes.note_count,
  notes.notes
FROM (SELECT DISTINCT
        date
      FROM (
             SELECT
               DATE(CONVERT_TZ(click_utc, '+00:00', '-07:00')) AS date
             FROM users_clicks
             UNION SELECT
                     DATE(CONVERT_TZ(click_utc, '+00:00', '-07:00')) AS date
                   FROM users_installs
             UNION SELECT
                     DATE(CONVERT_TZ(timestamp, '+00:00', '-07:00')) AS date
                   FROM reporting_notes) data) dates
  LEFT JOIN (SELECT
               DATE(CONVERT_TZ(min_click_utc, '+00:00', '-07:00')) AS date,
               COUNT(*)                                            AS clicks,
               SUM(max_costs)                                      AS costs
             FROM (SELECT
                     txid,
                     MIN(click_utc) AS min_click_utc,
                     MAX(cost)      AS max_costs
                   FROM users_clicks
                   GROUP BY txid) distinct_txids
             GROUP BY DATE(CONVERT_TZ(min_click_utc, '+00:00', '-07:00'))) clicks ON clicks.date = dates.date
  LEFT JOIN (SELECT
               DATE(CONVERT_TZ(min_click_utc, '+00:00', '-07:00')) AS date,
               COUNT(*)                                            AS installs
             FROM (SELECT
                     txid,
                     MIN(click_utc) AS min_click_utc
                   FROM users_installs
                   GROUP BY txid) distinct_txids
             GROUP BY DATE(CONVERT_TZ(min_click_utc, '+00:00', '-07:00'))) installs ON installs.date = dates.date
  LEFT JOIN (SELECT
               DATE(CONVERT_TZ(timestamp, '+00:00', '-07:00')) AS date,
               COUNT(*)                                        AS note_count,
               GROUP_CONCAT(note SEPARATOR ', ')               AS notes
             FROM reporting_notes
             GROUP BY DATE(CONVERT_TZ(timestamp, '+00:00', '-07:00'))) notes ON notes.date = dates.date;

答案 1 :(得分:1)

认为这需要加入子查询。

获取所使用的各种日期的一个子查询,然后将其与子查询相关联以获取点击次数和次点数,另一个获取安装次数: -

SELECT sub0.aDate, click_count, click_cost, install_count, GROUP_CONCAT(reporting_notes.note)
FROM
(
    SELECT DATE(click_utc) AS aDate
    FROM users_clicks
    UNION
    SELECT DATE(click_utc)
    FROM users_installs
    UNION
    SELECT DATE(timestamp)
    FROM reporting_notes
) sub0
LEFT OUTER JOIN
(
    SELECT DATE(click_utc) AS aDate, COUNT(txid) AS click_count, SUM(cost) AS click_cost
    FROM users_clicks
    GROUP BY aDate
) sub1
ON sub0.aDate = sub1.aDate
LEFT OUTER JOIN
(
    SELECT DATE(click_utc) AS aDate, COUNT(txid) AS install_count
    FROM users_installs
    GROUP BY aDate
) sub2
ON sub0.aDate = sub2.aDate
LEFT OUTER JOIN reporting_notes
ON sub0.aDate = DATE(reporting_notes.timestamp)
GROUP BY sub0.aDate, click_count, click_cost, install_count

如果你只想要独特的笔记并且不需要总和,这可以在没有子查询的情况下完成。