繁体   English   中英

整合MySQL查询

[英]Consolidating MySQL queries

我想知道如何将我使用的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"

所需的输出:数据集中每一天的点击次数,安装次数,总费用和任何注释

首先,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(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'));

每天安装:

 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 ,而没有FULL OUTER JOIN

 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(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;

如果您知道,查询会变得更容易,因为在安装的每一天,都会有一次单击,因此您也可以将单击查询用作日期池。 无论如何,我可能都会运行一个单独的查询来获取每天的注释,以便能够对文本进行操作。

只计数一次txid

并且此查询将确保在最早的时间,users_installs和users_clicks中的每个txid仅被计数一次。 由于还有两个子查询,因此性能(至少)会稍差一些。 如果txid已经不同的话,我会建议这样做。 如果您开始在子查询中过滤日期,则可以提高性能。

 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; 

认为这将需要联接子查询。

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

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

如果您只想要唯一的注释并且不需要总和,则可以在没有子查询进行计数的情况下完成此操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM