简体   繁体   English

从多个表的字段创建摘要VIEW

[英]Creating summary VIEW from fields from multiple tables

I am trying to write a select query for creating a view in MySQL. 我正在尝试编写一个用于在MySQL中创建视图的选择查询。 Each row in the view should display weekly summary (sum, avg) for user values collected from multiple tables. 视图中的每一行都应显示从多个表收集的用户值的每周摘要(总和,平均值)。 The tables are similar to each-other but not identical. 这些表彼此相似,但不相同。 The view should include rows also in case other table doesn't have a values for that week. 该视图还应包括行,以防其他表在该周没有值。 Something like this: 像这样:

| week_year | sum1 | avg1 | sum2 | user_id |
| --------- | ---- | ---- | ---- | ------- |
| 201840    |      |      | 3    | 1       |
| 201844    | 45   | 55   |      | 1       |
| 201845    | 55   | 65   |      | 1       |
| 201849    | 65   | 75   |      | 1       |
| 201849    | 75   | 85   | 3    | 2       |

The tables (simplified) are as follows: 这些表(简化后)如下:

CREATE TABLE IF NOT EXISTS `t1` (
  `user_id` INT NOT NULL AUTO_INCREMENT,
  `date` DATE NOT NULL,
  `value1` int(3) NOT NULL,
  `value2` int(3) NOT NULL,
  PRIMARY KEY (`user_id`,`date`)
) DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `t2` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `date` DATE NOT NULL,
  `value3` int(3) NOT NULL,
  PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;

CREATE TABLE IF NOT EXISTS `t3` (
  `t3_id` INT NOT NULL,
  `user_id` INT NOT NULL
) DEFAULT CHARSET=utf8;

My current solution doesn't seem reasonable and I am not sure how it would perform in case of thousands of rows: 我当前的解决方案似乎并不合理,我不确定在成千上万行的情况下它将如何执行:

select ifnull(yearweek(q1.date1), yearweek(q1.date2)) as week_year,
       sum(value1)                             as sum1,
       avg(value2)                              as avg1,
       sum(value3)                                   as sum2,
       q1.user_id
from (select t2.date as date2,
             t1.date as date1,
             ifnull(t3.user_id, t1.user_id) as user_id,
             t1.value1,
             t1.value2,
             t2.value3
      from t2
             join t3 on t3.t3_id=t2.id
             left join t1 on yearweek(t1.date) = yearweek(t2.date) and t1.user_id = t3.user_id
      union
      select t2.date as date2,
             t1.date as date1,
             ifnull(t3.user_id, t1.user_id) as user_id,
             t1.value1,
             t1.value2,
             t2.value3
      from t2
             join t3 on t3.t3_id=t2.id
             right join t1 on yearweek(t1.date) = yearweek(t2.date) and t1.user_id = t3.user_id) as q1

group by week_year, user_id;

DB Fiddle DB小提琴

Is the current solution okay performance wise or are there better options? 当前解决方案在性能上是否还可以,还是有更好的选择? In case of in the future third (or fourth) table is added, how would I manage the query? 如果将来添加了第三张(或第四张)表,我将如何管理查询? Should I consider creating a separate table, that is updated with triggers? 我是否应该考虑创建一个单独的表,并用触发器对其进行更新?

Thanks in advance. 提前致谢。

Another way you can do it is to union all the data and then group it. 您可以执行的另一种方法是合并所有数据,然后将其分组。 You'll have to perf test to see which is better: 您必须进行性能测试,看哪个更好:

SELECT

  yearweek(date), 
  SUM(value1) as sum1,
  AVG(value2) as avg1,
  SUM(value3) as sum2
FROM
(
  SELECT user_id, date, value1, value2, CAST(null as INT) as value3 FROM t1
  UNION ALL 
  SELECT user_id, date, null, null, value3 FROM t2 INNER JOIN t3 ON t2.id = t3.t3_id
)
GROUP BY
  user_id,
  yearweek(date)

Hopefully mysql won't take issue with casting null to an int.. 希望mysql不会将null转换为int的问题。

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

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