`limit` with `subQuery: false` return wrong result

See original GitHub issue

What are you doing?

Let’s say I have Transaction model which have many-to-many relation with Good model. And also belongs to User model. Here’s my model and relation definition.

module.exports = (sequelize, DataTypes) => {
  const Transaction = sequelize.define('Transaction', {
    id: {
      type: DataTypes.UUID,
      primaryKey: true,
      defaultValue: DataTypes.UUIDV4,
      allowNull: false,
      autoIncrement: false,
    },
    userId: {
      type: DataTypes.UUID,
      allowNull: false,
      foreignKey: true,
      references: {
        model: 'users',
        key: 'id',
      },
    },
    status: DataTypes.ENUM('verified', 'waiting', 'empty', 'rejected'),
    channel: {
      type: DataTypes.INTEGER,
      allowNull: false,
    },
  }, {});

  Transaction.associate = (models) => {
    Transaction.belongsTo(models.User, { as: 'user', foreignKey: 'userId' });
  };

  return Transaction;
};
module.exports = (sequelize, DataTypes) => {
  const Good = sequelize.define('Good', {
    id: {
      type: DataTypes.UUID,
      primaryKey: true,
      defaultValue: DataTypes.UUIDV4,
      allowNull: false,
      autoIncrement: false,
    },
    rphAset: {
      type: DataTypes.BIGINT,
      allowNull: false,
      defaultValue: 0,
    },
    urUpb: {
      type: DataTypes.STRING,
      allowNull: false,
    },
  }, {});

  return Good;
};
db.Good.belongsToMany(db.Transaction, { as: 'transactions', through: db.TransactionGood, foreignKey: 'goodId' });
db.Transaction.belongsToMany(db.Good, { as: 'goods', through: db.TransactionGood, foreignKey: 'transactionId' });

I already seed my database with data so user with id 30e1c140-d4d0-4edb-980a-3d7b9a47a958 has 7 transaction. I want to get transaction for that user with all goods in it. Here’s my code.

const x = await models.Transaction.findAll({
    subQuery: false,
    distinct: true,
    where: {
      userId: '30e1c140-d4d0-4edb-980a-3d7b9a47a958',
    },
    include: [
      {
        model: models.User,
        as: 'user',
        attributes: ['id','name','createdAt','updatedAt'],
      },
      {
        model: models.Good,
        as: 'goods',
      },
    ],
    order: [['createdAt','ASC',]],
    limit: 10,
  });

What do you expect to happen?

It will output array with 7 transcations data (all records in database).

What is actually happening?

It returns array with only 3 data. Here’s generated SQL

SELECT `Transaction`.`id`,
       `Transaction`.`userId`,
       `Transaction`.`status`,
       `Transaction`.`channel`,
       `Transaction`.`createdAt`,
       `Transaction`.`updatedAt`,
       `user`.`id` AS `user.id`,
       `user`.`name` AS `user.name`,
       `user`.`createdAt` AS `user.createdAt`,
       `user`.`updatedAt` AS `user.updatedAt`,
       `goods`.`id` AS `goods.id`,
       `goods`.`rphAset` AS `goods.rphAset`,
       `goods`.`urUpb` AS `goods.urUpb`,
       `goods`.`createdAt` AS `goods.createdAt`,
       `goods`.`updatedAt` AS `goods.updatedAt`,
       `goods->TransactionGood`.`id` AS `goods.TransactionGood.id`,
       `goods->TransactionGood`.`createdAt` AS `goods.TransactionGood.createdAt`,
       `goods->TransactionGood`.`updatedAt` AS `goods.TransactionGood.updatedAt`,
       `goods->TransactionGood`.`goodId` AS `goods.TransactionGood.goodId`,
       `goods->TransactionGood`.`transactionId` AS `goods.TransactionGood.transactionId`
FROM `Transactions` AS `Transaction`
LEFT OUTER JOIN `Users` AS `user`ON `Transaction`.`userId` = `user`.`id`
LEFT OUTER JOIN (`TransactionGoods` AS `goods->TransactionGood`
                 INNER JOIN`Goods` AS `goods` ON `goods`.`id` = `goods->TransactionGood`.`goodId`) ON `Transaction`.`id` = `goods->TransactionGood`.`transactionId`
WHERE `Transaction`.`userId` = '30e1c140-d4d0-4edb-980a-3d7b9a47a958'
ORDER BY `Transaction`.`createdAt` ASC
LIMIT 10;

But when I remove subQuery: false option it will return 7 data. Here’s generated sql without subQuery: false option.

SELECT `Transaction`.*,
       `user`.`id` AS `user.id`,
       `user`.`name` AS `user.name`,
       `user`.`createdAt` AS `user.createdAt`,
       `user`.`updatedAt` AS `user.updatedAt`,
       `goods`.`id` AS `goods.id`,
       `goods`.`rphAset` AS `goods.rphAset`,
       `goods`.`urUpb` AS `goods.urUpb`,
       `goods`.`createdAt` AS `goods.createdAt`,
       `goods`.`updatedAt` AS `goods.updatedAt`,
       `goods->TransactionGood`.`id` AS `goods.TransactionGood.id`,
       `goods->TransactionGood`.`createdAt` AS `goods.TransactionGood.createdAt`,
       `goods->TransactionGood`.`updatedAt` AS `goods.TransactionGood.updatedAt`,
       `goods->TransactionGood`.`goodId` AS `goods.TransactionGood.goodId`,
       `goods->TransactionGood`.`transactionId` AS `goods.TransactionGood.transactionId`
FROM
  (SELECT `Transaction`.`id`,
          `Transaction`.`userId`,
          `Transaction`.`status`,
          `Transaction`.`channel`,
          `Transaction`.`createdAt`,
          `Transaction`.`updatedAt`
   FROM `Transactions` AS `Transaction`
   WHERE `Transaction`.`userId` = '30e1c140-d4d0-4edb-980a-3d7b9a47a958'
   ORDER BY `Transaction`.`createdAt` ASC
   LIMIT 10) AS `Transaction`
LEFT OUTER JOIN `Users` AS `user` ON `Transaction`.`userId` = `user`.`id`
LEFT OUTER JOIN (`TransactionGoods` AS `goods->TransactionGood`
                 INNER JOIN `Goods` AS `goods` ON `goods`.`id` = `goods->TransactionGood`.`goodId`) ON `Transaction`.`id` = `goods->TransactionGood`.`transactionId`
ORDER BY `Transaction`.`createdAt` ASC;

Dialect: mysql Database version: 5.7.18 Sequelize version: 4.38.0 Tested with latest release: Yes

Note : Your issue may be ignored OR closed by maintainers if it’s not tested against latest version OR does not follow issue template.

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:2
  • Comments:25 (7 by maintainers)

github_iconTop GitHub Comments

48reactions
AlexBykovMinskcommented, Sep 5, 2019

@papb FYI: In my case the issue takes place, when I include models with @ HasMany relations. I solved my issue by setting “separate” flag to true

include: [
    {
        model: Offer,
        as: "offers",
        required: false,
        separate: true
    },
    {
        model: DealFund,
        as: "fund",
        include: [
            {
                model: DealFundCharge,
                as: "charges",
                required: false,
                separate: true
            }
        ]
    }
]

Alex

23reactions
davidadascommented, Apr 21, 2019

Has there been any progress whatsoever? This is a big deal.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Sequelize query returning the wrong number of rows when ...
query.limit = 12). This works fine if I don't include any associated rows, but when I include the related models it returns 7...
Read more >
sequelize/core - HasOneCreateAssociationMixinOptions
Use sub queries (internal). If unspecified, this will true by default if limit is specified, and false otherwise. See limit for more information....
Read more >
sequelize limit not working
If you don't care about having the limit in the subquery there's no reason to have the subquery at all, so you can...
Read more >
Subqueries | BigQuery - Google Cloud
Returns TRUE if value is in the set of rows returned by the subquery. Returns FALSE if the subquery returns zero rows. The...
Read more >
Subqueries (SQL Server) - Microsoft Learn
A subquery introduced with an unmodified comparison operator (a comparison operator not followed by ANY or ALL ) must return a single value ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found