sequelize: Problem using order and limit together when eager loading associations

I have a transaction table with multiple columns that correspond to primary keys in master tables. Basically simple one to one relations.

When I use limit and order and I am eager loading all the relations in the findAll function, the resulting query generates a subquery for the FROM clause which is used by the LIMIT. The ORDER on the other hand is applied to the outer query. I am using LIMIT as there could be a zillion transactions and I need to page through them in a sane way.

This does not provide the desired result as the order is not applied on the entire data set but rather on the set that is returned by the subquery.

Is there a way I can apply the order on the subquery as well?

I am using Sequelize 1.7.9

db.Transaction.findAll({
          order: '`transactions`.`some_date` DESC',
          limit: 10,
          offset: 10,
          include: [{
            model: db.Master1,
            attributes:['name'],
            include: [{
              model: db.Master2,
              attributes:['name']
            }]
          }, {
            model: db.Master3,
            include: [{
              model: db.Master4,
              attributes: ['name']
            }]
          }, {
            model: db.Master5,
            attributes: ['name'],
            where: {
              id: '12345'
            }
          }]          
        })

yields SQL of the form

SELECT `transactions`.*,
       `master1`.`name` AS `master1.name`,
       `master1.master2`.`name` AS `master1.master2.name`,
       `master3`.`name` AS `master3.name`,
       `master3.master4`.`name` AS `master3.master4.name`       
FROM
  (SELECT `transactions`.*,
          `master5`.`id` AS `master5.id`
   FROM `transactions`
   INNER JOIN `master5` AS `master5` ON `master5`.`id` = `transactions`.`session_id`
   AND `master5`.`id`='12345' LIMIT 10, 10) AS `transactions`
LEFT OUTER JOIN `master1s` AS `master1` ON `master1`.`id` = `transactions`.`id`
LEFT OUTER JOIN `master2s` AS `master1.master2` ON `master1.master2`.`id` = `master1`.`id_fk`
LEFT OUTER JOIN `master3s` AS `master3` ON `master3`.`id` = `transactions`.`master3_id`
LEFT OUTER JOIN `master4s` AS `master3.master4` ON `master3.master4`.`id` = `master3`.`master4_id`
ORDER BY `transactions`.`some_date` DESC;

Can the order be somehow shifted into the subquery?

SELECT `transactions`.*,
       `master1`.`name` AS `master1.name`,
       `master1.master2`.`name` AS `master1.master2.name`,
       `master3`.`name` AS `master3.name`,
       `master3.master4`.`name` AS `master3.master4.name`       
FROM
  (SELECT `transactions`.*,
          `master5`.`id` AS `master5.id`
   FROM `transactions`
   INNER JOIN `master5` AS `master5` ON `master5`.`id` = `transactions`.`session_id`
   AND `master5`.`id`='12345'  
   ORDER BY `transactions`.`some_date` DESC 
   LIMIT 10, 10) AS `transactions`
LEFT OUTER JOIN `master1s` AS `master1` ON `master1`.`id` = `transactions`.`id`
LEFT OUTER JOIN `master2s` AS `master1.master2` ON `master1.master2`.`id` = `master1`.`id_fk`
LEFT OUTER JOIN `master3s` AS `master3` ON `master3`.`id` = `transactions`.`master3_id`
LEFT OUTER JOIN `master4s` AS `master3.master4` ON `master3.master4`.`id` = `master3`.`master4_id`;

About this issue

  • Original URL
  • State: closed
  • Created 10 years ago
  • Reactions: 10
  • Comments: 30 (10 by maintainers)

Most upvoted comments

There’s still an issue when trying to sort by both “parent” and “child” table fields. In SQL I would expect the inner query to have parent’s sorting clause, and the outer to include the child’s “order by”. But at the moment it can only include both into both queries which definitely causes an error in SQL because the child table reference in the inner query is not defined (i.e. it says "missing FROM-clause entry for table “child”). Any workarounds for this case?

So, I have had this problem yesterday, I was including another model and I am using pagination (obviously limit and offset are a must) and there is a need for order by clause as well.

I tried this: queryParams.order = 'created_at DESC' - no go, complains that “created_at” column doesnt exist. then this: queryParams.order = [['created_at', 'DESC']] - only did sorting on first batch of results so after re-reading the documentation I decided to try this:

queryParams.order = [
   [models.sequelize.col('"createdAt"'), 'DESC']
];

this produced correct SQL and data was being sorted properly on every page (limit + offset).

In my case the issue was “aliased” columns + incorrect positioning of order by clause.

I ran into the same problem and the @lucaswxp answer helped me as well.