【问题标题】:How to get max values of table with sequelize model.findAll()如何使用 sequelize model.findAll() 获取表的最大值
【发布时间】:2021-06-23 23:47:07
【问题描述】:

我有一个用例,必须将对 Products 表所做的每个更改存储为已更改行的版本。所以我的表由如下行组成:

https://i.stack.imgur.com/zXJ8S.png

所以,当我们使用model.findAll() 时,它将返回所有行,包括每行的版本。这对于历史视图来说很好。这里的问题是,我们如何在不返回以前版本(旧更改)的情况下获取表中所有最新版本的行?我有点担心我们可以使用 sequelize max 属性来实现这一点。但不确定如何使用它来实现我的用例。谁能告诉我该怎么做?谢谢

【问题讨论】:

    标签: javascript mysql node.js postgresql sequelize.js


    【解决方案1】:

    拍续集之前

    有几种方法可以解决,尽管子查询是您可以做到的方法之一。

    我已经演示了在 where 子句中添加一个带有 max 函数的子查询。

    让我们首先在简单的mysql中复制它

    mysql> create table product (productId VARCHAR(200), docversion integer, name VARCHAR(200), price integer, location VARCHAR(200));
    Query OK, 0 rows affected (1.01 sec)
    
    mysql> insert into product(productID, docversion, name, price, location) VALUES('PID123', 0, 'Chair', 25, 'USA');
    Query OK, 1 row affected (0.07 sec)
    
    mysql> insert into product(productID, docversion, name, price, location) VALUES('PID123', 1, 'Chair', 32, 'USA');
    Query OK, 1 row affected (0.12 sec)
    
    mysql> insert into product(productID, docversion, name, price, location) VALUES('PID456', 0, 'Table', 39, 'UK');
    Query OK, 1 row affected (0.16 sec)
    
    mysql> insert into product(productID, docversion, name, price, location) VALUES('PID456', 1, 'Table', 43, 'Canada');
    Query OK, 1 row affected (0.08 sec)
    
    mysql> insert into product(productID, docversion, name, price, location) VALUES('PID123', 2, 'Chair', 29, 'UK');
    Query OK, 1 row affected (0.09 sec)
    
    mysql> select * from product;
    +-----------+------------+-------+-------+----------+
    | productId | docversion | name  | price | location |
    +-----------+------------+-------+-------+----------+
    | PID123    |          0 | Chair |    25 | USA      |
    | PID123    |          1 | Chair |    32 | USA      |
    | PID456    |          0 | Table |    39 | UK       |
    | PID456    |          1 | Table |    43 | Canada   |
    | PID123    |          2 | Chair |    29 | UK       |
    +-----------+------------+-------+-------+----------+
    5 rows in set (0.00 sec)
    
    
    mysql> select * from product where  location='USA' AND name='Chair' AND docversion = (select max(docversion) from product where location='USA' AND name='Chair' group by productId);
    +-----------+------------+-------+-------+----------+
    | productId | docversion | name  | price | location |
    +-----------+------------+-------+-------+----------+
    | PID123    |          1 | Chair |    32 | USA      |
    +-----------+------------+-------+-------+----------+
    1 row in set (0.01 sec)
    

    现在将相同的查询转换为 sequelize

    product.findAll({
      where: {
          location:{
              [Op.eq]: 'USA',
          },
          name:{
              [Op.eq]: 'Chair',
          },
          docversion:{
              [Op.eq]: sequelize.literal(`select max(docversion) from product where location='USA' AND name='Chair' group by productId`),
          },
      }
    })
    

    【讨论】:

    • 感谢您的详细回答。我只是想在表格中列出所有产品(最新版本),而没有任何进一步的 where 条件。我们能得到吗?谢谢
    • 是的,您可以从中删除任何条件,应该很容易 product.findAll({ where: { docversion:{ [Op.eq]: sequelize.literal(select max(docversion) from product where group by productId), }, } 虽然,如果您不需要任何 where 条件,那么您可能需要在 FROM 部分中创建子查询
    • 这似乎不起作用。你能告诉我吗?获取syntax error at or near 'select'
    • 缺少反引号 product.findAll({ where: { docversion:{ [Op.eq]: sequelize.literal(`select max(docversion) from product where group by productId`), }, } )
    • 抛出错误:more than one row returned by a subquery used as an expression。然后尝试使用OP.in,它也返回重复值,即。同一文档的先前版本。有什么办法,我们可以用 max groupby 防止重复?
    猜你喜欢
    • 2020-04-07
    • 2021-09-17
    • 1970-01-01
    • 1970-01-01
    • 2019-10-16
    • 1970-01-01
    • 2021-11-13
    • 1970-01-01
    • 2020-09-22
    相关资源
    最近更新 更多