[英]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仅具有LEFT
或RIGHT 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;
如果您知道,查询会变得更容易,因为在安装的每一天,都会有一次单击,因此您也可以将单击查询用作日期池。 无论如何,我可能都会运行一个单独的查询来获取每天的注释,以便能够对文本进行操作。
并且此查询将确保在最早的时间,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.