根据不同的值查询多个 MySQL 表,并且 return 匹配计数和第一条记录和最后一条记录之间的时间差

Querying multiple MySQL tables based on distinct values, and return the matches count and time difference between first and last record

问题总结

我需要 select table 中列 slug 的所有不同值,然后遍历其他多个 table,并对每个记录进行计数slug 出现,并找出第一次和最后一次出现之间的天数差异。


示例数据

假设 table 包含对项目的引用,另外 tables 包含每个项目的定时记录。 让我们使用设备示例以及 CPU、RAM 和 GPU 使用指标在不同时间的记录,基于每个设备。

+---------------------------+-----------------------------+-----------------------------+---------------------------------+
| Table `devices`           | Table `cpu`                 | Table `ram`                 | Table `gpu`                     |
+---------------------------+-----------------------------+-----------------------------+---------------------------------+
| slug (varchar, prim. key) | slug (varchar, prim. key)   | slug (varchar, prim. key)   | slug (varchar, prim. key)       |
+---------------------------+-----------------------------+-----------------------------+---------------------------------+
| created (timestamp)       | time (timestamp, prim. key) | date (timestamp, prim. key) | log_time (timestamp, prim. key) |
+---------------------------+-----------------------------+-----------------------------+---------------------------------+
| 30d_users (int)           | cpu_use (float)             | ram_use (float)             | gpu_use (float)                 |
+---------------------------+-----------------------------+-----------------------------+---------------------------------+
| 7d_users                  |                             |                             |                                 |
+---------------------------+-----------------------------+-----------------------------+---------------------------------+

为了示例,让我们在这些值上填充一些值:

+---------+---------------------+-----------+----------+
| slug    | created             | 30d_users | 7d_users |
+---------+---------------------+-----------+----------+
| desktop | 2021-02-18 05:10:04 | 1982      | 713      |
+---------+---------------------+-----------+----------+
| laptop  | 2021-02-16 05:10:04 | 1783      | 449      |
+---------+---------------------+-----------+----------+
| tablet  | 2021-02-19 05:10:04 | 119       | 8        |
+---------+---------------------+-----------+----------+
| phone   | 2021-02-27 05:10:04 | 2263      | 1567     |
+---------+---------------------+-----------+----------+
+-----------------------------------------+---+-----------------------------------------+---+-----------------------------------------+
|                CPU Table                | • |                RAM Table                | • |                GPU Table                |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| slug    | time                | cpu_use | • | slug    | date                | ram_use | • | slug    | log_time            | gpu_use |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| tablet  | 2021-03-14 05:10:06 | 72      | • | desktop | 2021-03-14 05:10:06 | 57      | • | phone   | 2021-03-14 05:10:06 | 64      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| phone   | 2021-03-14 05:10:07 | 33      | • | laptop  | 2021-03-14 05:10:07 | 84      | • | desktop | 2021-03-14 05:10:07 | 48      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| laptop  | 2021-03-15 05:10:04 | 93      | • | tablet  | 2021-03-14 05:10:04 | 31      | • | laptop  | 2021-03-15 05:10:04 | 51      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| desktop | 2021-03-16 05:10:05 | 31      | • | phone   | 2021-03-14 05:10:05 | 64      | • | desktop | 2021-03-15 05:10:05 | 29      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| tablet  | 2021-03-16 05:10:05 | 47      | • | desktop | 2021-03-16 05:10:05 | 90      | • | phone   | 2021-03-15 05:10:05 | 82      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| phone   | 2021-03-16 05:10:06 | 37      | • | tablet  | 2021-03-16 05:10:06 | 84      | • | phone   | 2021-03-16 05:10:06 | 71      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| laptop  | 2021-03-16 05:10:07 | 28      | • | laptop  | 2021-03-16 05:10:07 | 98      | • | laptop  | 2021-03-16 05:10:07 | 76      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| phone   | 2021-03-17 05:10:06 | 94      | • | desktop | 2021-03-17 05:10:06 | 28      | • | phone   | 2021-03-17 05:10:06 | 79      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| desktop | 2021-03-17 05:10:07 | 87      | • | phone   | 2021-03-17 05:10:07 | 17      | • | desktop | 2021-03-17 05:10:07 | 34      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| tablet  | 2021-03-17 05:10:08 | 93      | • | tablet  | 2021-03-17 05:10:08 | 67      | • | tablet  | 2021-03-17 05:10:08 | 38      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| laptop  | 2021-03-17 05:10:09 | 54      | • | laptop  | 2021-03-17 05:10:09 | 96      | • | laptop  | 2021-03-17 05:10:09 | 95      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| desktop | 2021-03-18 05:10:07 | 21      | • | tablet  | 2021-03-18 05:10:07 | 50      | • | tablet  | 2021-03-18 05:10:07 | 32      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| laptop  | 2021-03-18 05:10:08 | 17      | • | laptop  | 2021-03-18 05:10:08 | 30      | • | laptop  | 2021-03-18 05:10:08 | 27      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| tablet  | 2021-03-19 05:10:08 | 42      | • | tablet  | 2021-03-19 05:10:08 | 79      | • | tablet  | 2021-03-19 05:10:08 | 26      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| phone   | 2021-03-19 05:10:09 | 30      | • | phone   | 2021-03-19 05:10:09 | 80      | • | tablet  | 2021-03-19 05:10:09 | 64      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| desktop | 2021-03-19 05:10:10 | 81      | • | desktop | 2021-03-19 05:10:10 | 60      | • | desktop | 2021-03-19 05:10:10 | 91      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| laptop  | 2021-03-19 05:10:11 | 63      | • | laptop  | 2021-03-19 05:10:11 | 71      | • | laptop  | 2021-03-19 05:10:11 | 67      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| laptop  | 2021-03-20 05:10:09 | 93      | • | laptop  | 2021-03-20 05:10:09 | 95      | • | laptop  | 2021-03-20 05:10:09 | 95      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| desktop | 2021-03-20 05:10:10 | 76      | • | phone   | 2021-03-20 05:10:10 | 40      | • | phone   | 2021-03-20 05:10:10 | 37      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| tablet  | 2021-03-20 05:10:11 | 87      | • | tablet  | 2021-03-20 05:10:11 | 61      | • | tablet  | 2021-03-20 05:10:11 | 69      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| desktop | 2021-03-21 05:10:10 | 92      | • | desktop | 2021-03-21 05:10:10 | 45      | • | desktop | 2021-03-21 05:10:10 | 80      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| phone   | 2021-03-22 05:10:11 | 67      | • | phone   | 2021-03-22 05:10:11 | 54      | • | phone   | 2021-03-24 05:10:11 | 48      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+
| desktop | 2021-03-22 05:10:12 | 47      | • | laptop  | 2021-03-26 05:10:12 | 90      | • | tablet  | 2021-03-29 05:10:12 | 22      |
+---------+---------------------+---------+---+---------+---------------------+---------+---+---------+---------------------+---------+

期望的结果

现在,假设我想要 运行 一个通过以下方式获取摘要的查询:

  1. devices table
  2. 中的每个 slug
  3. 检查 cpuramgpu 上每个 slug 的记录数
  4. 获取这些table中的第一个和最后一个匹配记录(分别为time/datelog_time
  5. 计算第一条记录和最后一条记录之间的天数差异
  6. Returns结构为slug-table_name_diff-table_name_count的结果(乘以查询的个数table,本例为3上面的例子)

例如,采用上面的示例数据,结果将是:

+---------+-----------+----------+-----------+----------+-----------+----------+
| slug    | cpu_count | cpu_diff | ram_count | ram_diff | gpu_count | gpu_diff |
+---------+-----------+----------+-----------+----------+-----------+----------+
| desktop | 7         | 6        | 5         | 7        | 5         | 7        |
+---------+-----------+----------+-----------+----------+-----------+----------+
| laptop  | 6         | 5        | 7         | 10       | 6         | 5        |
+---------+-----------+----------+-----------+----------+-----------+----------+
| tablet  | 5         | 6        | 6         | 6        | 6         | 12       |
+---------+-----------+----------+-----------+----------+-----------+----------+
| phone   | 5         | 8        | 5         | 8        | 6         | 10       |
+---------+-----------+----------+-----------+----------+-----------+----------+

我设法仅针对单个 table 实现了这一点,(但不是针对多个 table,并且没有从 devices [中获取 slug 值=68=]), 通过查询:

SELECT DISTINCT slug, DATEDIFF(MAX(time), MIN(time)) as cpu_diff, COUNT(*) 
FROM cpu 
GROUP BY slug 
ORDER BY `cpu_diff` DESC

你走对了!

考虑从现有方法构建:

WITH cpu_summary AS (
  SELECT slug
       , DateDiff(dd, Max(time), Min(time) AS cpu_diff
       , Count(*) AS cpu_count
  FROM   cpu
  GROUP
      BY slug
)
, ram_summary AS (
  <a very similar looking query to the above one, but on the ram table>
)
, gpu_summary AS (
  <take a guess ;-)>
)
SELECT devices.slug
     , cpu_summary.cpu_diff
     , cpu_summary.cpu_count
     , ram_summary.ram_diff
     , ram_summary.ram_count
     , gpu_summary.gpu_diff
     , gpu_summary.gpu_count
FROM   devices
 LEFT
  JOIN cpu_summary
    ON cpu_summary.slug = devices.slug
 LEFT
  JOIN ram_summary
    ON ram_summary.slug = devices.slug
 LEFT
  JOIN gpu_summary
    ON gpu_summary.slug = devices.slug
;