首先:MySQL 能够处理命名时区,但您需要先填充时区信息表。请参阅 CONVERT_TZ 的文档作为起点。
由于您的表似乎不相关(即没有包含所有 txids 的主表,...)您可能最好使用在开始时接近触发单独查询的子查询。
点击次数和每日费用:
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 只有LEFT 或RIGHT OUTER JOINs,但没有FULL OUTER JOINs:
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;
如果您知道,在发生安装的每一天,还会有一次点击,查询会变得更容易,因为您可以将点击查询也用作日期池。无论如何,我可能会运行一个单独的查询来获取每天的笔记,以便能够对文本采取行动。
只计算一次 txid
并且此查询将确保 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;