【问题标题】:Only include values from the latest timestamp into the query result仅将最新时间戳中的值包含到查询结果中
【发布时间】:2020-10-20 09:37:06
【问题描述】:

DB-Fiddle

CREATE TABLE sales (
    id int auto_increment primary key,
    time_stamp TIMESTAMP,
    product VARCHAR(255),
    sales_quantity INT
);

INSERT INTO sales
(time_stamp, product, sales_quantity)
VALUES 
("2020-01-14 07:15:30", "Product_A", "100"),
("2020-01-14 07:15:30", "Product_B", "300"),
("2020-01-14 07:18:45", "Product_A", "200"),
("2020-01-14 07:18:45", "Product_B", "900"),

("2020-01-15 07:19:23", "Product_A", "400"),
("2020-01-15 07:19:23", "Product_B", "270"),
("2020-01-15 07:45:10", "Product_A", "900"),
("2020-01-15 07:45:10", "Product_B", "340");

预期结果:

time_stamp             sales_quantity
2020-01-14              1.100
2020-01-15              1.240

正如您在表格中看到的,每天有多个TIMESTAMP
现在,我想为每个TIMESTAMP 查询sales_quantitysum,但只有lates 的 应该包含

因此,在示例中,TIMESTAMP07:15:3007:19:23 应被忽略。

我试着用这个查询:

SELECT
MAX(time_stamp),
SUM(sales_quantity) AS sales_quantity
FROM sales
GROUP BY 1;

但是,我收到错误 Can't group on 'MAX(time_stamp)'
我需要如何修改查询以获得预期的结果?

【问题讨论】:

    标签: mysql sql datetime sum subquery


    【解决方案1】:

    一个选项使用相关子查询进行过滤:

    select date(time_stamp) date_stamp, sum(product) sales_quantity
    from sales s
    where s.time_stamp = (
        select max(s1.time_stamp) 
        from sales s1 
        where s1.time_stamp >= date(s.time_stamp) and s1.time_stamp < date(s.time_stamp) + interval 1 day
    )
    group by date_stamp
    order by date_stamp
    

    如果你运行的是 MySQL 8.0,你也可以使用rank():

    select date(time_stamp) date_stamp, sum(product) sales_quantity
    from (
        select s.*, rank() over(partition by date(time_stamp) order by time_stamp desc) rn
        from sales s
    ) t
    where rn = 1
    group by date_stamp
    order by date_stamp
    

    【讨论】:

      【解决方案2】:

      您可以使用CTE 对每天的time_stamp 值进行降序排列(我们使用DENSE_RANK,以便所有具有最新time_stamp 的行获得行号1),然后SUM 排名为 1 的行的数量(即当天的最新值):

      WITH CTE AS (
        SELECT time_stamp,
               sales_quantity,
               DENSE_RANK() OVER (PARTITION BY DATE(time_stamp) ORDER BY time_stamp DESC) AS rn
        FROM sales
      )
      SELECT DATE(time_stamp) AS time_stamp,
             SUM(sales_quantity) AS sales_quantity
      FROM CTE
      WHERE rn = 1
      GROUP BY time_stamp
      

      输出:

      time_stamp  sales_quantity
      2020-01-14  1100
      2020-01-15  1240
      

      Demo on dbfiddle

      【讨论】:

        【解决方案3】:

        您需要在WHERE 子句中使用带有NOT EXISTS 的条件,以便只聚合每天最新的time_stamp 行:

        SELECT DATE(s.time_stamp) time_stamp,
               SUM(s.sales_quantity) sales_quantity
        FROM sales s
        WHERE NOT EXISTS (SELECT 1 FROM sales WHERE DATE(time_stamp) = DATE(s.time_stamp) AND time_stamp > s.time_stamp)
        GROUP BY DATE(s.time_stamp);
        

        请参阅demo

        如果您使用的是 MySql 8.0+ 而不是 MariaDB 10.3(就像您的小提琴一样),那么您也可以使用 FIRST_VALUE() 窗口函数:

        SELECT DISTINCT
               DATE(s.time_stamp) time_stamp,
               FIRST_VALUE(SUM(s.sales_quantity)) OVER (PARTITION BY DATE(s.time_stamp) ORDER BY s.time_stamp DESC) sales_quantity
        FROM sales s
        GROUP BY s.time_stamp;
        

        请参阅demo

        结果:

        > time_stamp | sales_quantity
        > :--------- | -------------:
        > 2020-01-14 |           1100
        > 2020-01-15 |           1240
        

        【讨论】:

          【解决方案4】:

          尝试在选择列表中包含产品并对其进行分组,例如;

           SELECT
           product,
           MAX(time_stamp),
           SUM(sales_quantity) AS sales_quantity
           FROM sales
           GROUP BY product;
          

          "group by 1" 尝试根据您的第一列 max(time_stamp) 对其进行分组

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-04-27
            • 1970-01-01
            • 2016-03-09
            • 2014-03-08
            • 2018-09-20
            • 2018-10-22
            • 1970-01-01
            相关资源
            最近更新 更多