【问题标题】:how to count min, max and average from this query mysql 5.7如何从此查询mysql 5.7中计算最小值、最大值和平均值
【发布时间】:2020-08-27 13:22:43
【问题描述】:

这是我的小提琴https://dbfiddle.uk/?rdbms=mysql_5.7&fiddle=1dbde0d6227268a4eee4dee539a5d930

假设我有这张桌子

CREATE TABLE test (
  ID INT,
  user_id INT,
  createdAt DATE,
  status_id INT
);

INSERT INTO test VALUES
  (1, 13, '2020-01-01', 8),
  (2, 13, '2020-01-03', 8),
  (3, 13, '2020-01-06', 8),
  (4, 13, '2020-01-02', 7),
  (5, 13, '2020-01-03', 7),
  (6, 14, '2020-03-03', 8),
  (7, 13, '2020-03-04', 4),
  (8, 15, '2020-04-04', 7),
  (9, 14, '2020-03-02', 6),
  (10, 14, '2020-03-10', 5),
  (11, 13, '2020-04-10', 8);

我想为这个查询所需的日期时间范围内的每个用户计算不同的时间

SELECT t1.user_id, 
       t1.createdAt cretecompare1, 
       t2.createdAt cretecompare2,
       DATEDIFF(t2.createdAt, t1.createdAt) diff
-- table for a transaction
FROM test t1
-- table for prev. transaction
JOIN test t2 ON t1.user_id = t2.user_id 
            AND t1.createdAt < t2.createdAt
            AND 7 NOT IN (t1.status_id, t2.status_id)
JOIN (SELECT t3.user_id
      FROM test t3
      WHERE t3.status_id != 7
      GROUP BY t3.user_id
      HAVING SUM(t3.createdAt < '2020-04-01') > 1
         AND SUM(t3.createdAt BETWEEN '2020-02-01' AND '2020-04-01')) t4 ON t1.user_id = t4.user_id
WHERE NOT EXISTS (SELECT NULL
                   FROM test t5
                   WHERE t1.user_id = t5.user_id
                     AND t5.status_id != 7
                     AND t1.createdAt < t5.createdAt
                     AND t5.createdAt < t2.createdAt) 
HAViNG cretecompare2  BETWEEN '2020-02-01' AND '2020-04-01';

之后的结果是这样的

+----------+---------------+---------------+------+
|  user_id | cretecompare1 | cretecompare2 | diff |
+----------+---------------+---------------+------+
|       14 | 2020-03-02    | 2020-03-03    |    1 |
|       13 | 2020-01-06    | 2020-03-04    |   58 |
|       14 | 2020-03-03    | 2020-03-10    |    7 |
+----------+---------------+---------------+------+

我想用这个查询计算最大差异、最小差异和差异的平均值

SELECT t1.user_id, 
       t1.createdAt cretecompare1, 
       t2.createdAt cretecompare2,
       DATEDIFF(t2.createdAt, t1.createdAt) diff,
       MIN(DATEDIFF(t2.createdAt, t1.createdAt)) min_diff, 
       MAX(DATEDIFF(t2.createdAt, t1.createdAt)) max_diff, 
       AVG(DATEDIFF(t2.createdAt, t1.createdAt)) avg_diff
-- table for a transaction
FROM test t1
-- table for prev. transaction
JOIN test t2 ON t1.user_id = t2.user_id 
            AND t1.createdAt < t2.createdAt
            AND 7 NOT IN (t1.status_id, t2.status_id)
JOIN (SELECT t3.user_id
      FROM test t3
      WHERE t3.status_id != 7
      GROUP BY t3.user_id
      HAVING SUM(t3.createdAt < '2020-04-01') > 1
         AND SUM(t3.createdAt BETWEEN '2020-02-01' AND '2020-04-01')) t4 ON t1.user_id = t4.user_id
WHERE NOT EXISTS (SELECT NULL
                   FROM test t5
                   WHERE t1.user_id = t5.user_id
                     AND t5.status_id != 7
                     AND t1.createdAt < t5.createdAt
                     AND t5.createdAt < t2.createdAt) 
HAViNG cretecompare2  BETWEEN '2020-02-01' AND '2020-04-01'

它说

In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'db_2015623402.t1.user_id'; this is incompatible with sql_mode=only_full_group_by

预期结果

+-----+-----+---------+
| MIN | MAX | AVERAGE |
+-----+-----+---------+
|   1 |  58 |      22 |
+-----+-----+---------+

【问题讨论】:

    标签: mysql


    【解决方案1】:

    这样就可以了。您正在寻找您拥有的数据中的数据摘要,因此您可以将其包装在 SELECT () 中,在最后为整个内容指定别名 (t) 并使用 min()max() 等函数,和avg() 正常。

    SELECT min(diff) as min, max(diff) as max, format(avg(diff),0) as avg  FROM (SELECT t1.user_id, 
           t1.createdAt cretecompare1, 
           t2.createdAt cretecompare2,
           DATEDIFF(t2.createdAt, t1.createdAt) diff
    -- table for a transaction
    FROM test t1
    -- table for prev. transaction
    JOIN test t2 ON t1.user_id = t2.user_id 
                AND t1.createdAt < t2.createdAt
                AND 7 NOT IN (t1.status_id, t2.status_id)
    JOIN (SELECT t3.user_id
          FROM test t3
          WHERE t3.status_id != 7
          GROUP BY t3.user_id
          HAVING SUM(t3.createdAt < '2020-04-01') > 1
             AND SUM(t3.createdAt BETWEEN '2020-02-01' AND '2020-04-01')) t4 ON t1.user_id = t4.user_id
    WHERE NOT EXISTS (SELECT NULL
                       FROM test t5
                       WHERE t1.user_id = t5.user_id
                         AND t5.status_id != 7
                         AND t1.createdAt < t5.createdAt
                         AND t5.createdAt < t2.createdAt) 
    HAViNG cretecompare2  BETWEEN '2020-02-01' AND '2020-04-01') t
    

    【讨论】:

      猜你喜欢
      • 2014-11-20
      • 2016-09-15
      • 1970-01-01
      • 2016-11-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-01
      相关资源
      最近更新 更多