web-dev-qa-db-fra.com

Limiter et compenser le placement incorrect dans la requête

J'utilise sequelize dans nodeJs et j'ai ce code:

Time_Sheet_Details.findAll({
include: [
    {
        model: timesheetNotesSubcon,
        required: false,
        attributes:["note","file_name", "id", "working_hrs", "timestamp", "has_screenshot", "notes_category"]
    },
    {
        model: Timesheet,
        attributes:["id","leads_id","userid"],
        include:[
            {
                model: Lead_Info, attributes:["id","fname","lname","email","hiring_coordinator_id","status"],
                where: { hiring_coordinator_id : 326},
                include:[{
                    model: adminInfoSchema,
                    required: false,
                    attributes:["admin_id","admin_fname", "admin_lname", "admin_email", "signature_contact_nos", "signature_company"],      
                }]

            },
            {model:Personal_Info,attributes:["userid","fname","lname","email"]}
        ],
    }],
where: { 
    reference_date: filters.reference_date
},
order:[
    ["id","DESC"]
],
offset:((1-1)*30),
limit : 30,

}).then(function(foundObject){
    willFulfillDeferred.resolve(foundObject);
});

Et la requête de résultat est:

SELECT `timesheet_details`.*, `timesheet_notes_subcons`.`note` AS `timesheet_notes_subcons.note`, `timesheet_notes_subcons`.`file_name` AS `timesheet_notes_subcons.file_name`, `timesheet_notes_subcons`.`id` AS `timesheet_notes_subcons.id`, `timesheet_notes_subcons`.`working_hrs` AS `timesheet_notes_subcons.working_hrs`, `timesheet_notes_subcons`.`timestamp` AS `timesheet_notes_subcons.timestamp`, `timesheet_notes_subcons`.`has_screenshot` AS `timesheet_notes_subcons.has_screenshot`, `timesheet_notes_subcons`.`notes_category` AS `timesheet_notes_subcons.notes_category`, `timesheet.lead`.`id` AS `timesheet.lead.id`, `timesheet.lead`.`fname` AS `timesheet.lead.fname`, `timesheet.lead`.`lname` AS `timesheet.lead.lname`, `timesheet.lead`.`email` AS `timesheet.lead.email`, `timesheet.lead`.`hiring_coordinator_id` AS `timesheet.lead.hiring_coordinator_id`, `timesheet.lead`.`status` AS `timesheet.lead.status`, `timesheet.lead.admin`.`admin_id` AS `timesheet.lead.admin.admin_id`, `timesheet.lead.admin`.`admin_fname` AS `timesheet.lead.admin.admin_fname`, `timesheet.lead.admin`.`admin_lname` AS `timesheet.lead.admin.admin_lname`, `timesheet.lead.admin`.`admin_email` AS `timesheet.lead.admin.admin_email`, `timesheet.lead.admin`.`signature_contact_nos` AS `timesheet.lead.admin.signature_contact_nos`, `timesheet.lead.admin`.`signature_company` AS `timesheet.lead.admin.signature_company`, `timesheet.personal`.`userid` AS `timesheet.personal.userid`, `timesheet.personal`.`fname` AS `timesheet.personal.fname`, `timesheet.personal`.`lname` AS `timesheet.personal.lname`, `timesheet.personal`.`email` AS `timesheet.personal.email` FROM (SELECT `timesheet_details`.`id`, `timesheet_details`.`timesheet_id`, `timesheet_details`.`day`, `timesheet_details`.`total_hrs`, `timesheet_details`.`adj_hrs`, `timesheet_details`.`regular_rostered`, `timesheet_details`.`hrs_charged_to_client`, `timesheet_details`.`diff_charged_to_client`, `timesheet_details`.`hrs_to_be_subcon`, `timesheet_details`.`diff_paid_vs_adj_hrs`, `timesheet_details`.`status`, `timesheet_details`.`reference_date`, `timesheet`.`id` AS `timesheet.id`, `timesheet`.`leads_id` AS `timesheet.leads_id`, `timesheet`.`userid` AS `timesheet.userid` FROM `timesheet_details` AS `timesheet_details` LEFT OUTER JOIN `timesheet` AS `timesheet` ON `timesheet_details`.`timesheet_id` = `timesheet`.`id` WHERE (`timesheet_details`.`reference_date` >= '2016-04-23 16:00:00' AND `timesheet_details`.`reference_date` < '2017-05-02 15:59:59') ORDER BY `timesheet_details`.`id` DESC LIMIT 0, 30) AS `timesheet_details` LEFT OUTER JOIN `timesheet_notes_subcon` AS `timesheet_notes_subcons` ON `timesheet_details`.`id` = `timesheet_notes_subcons`.`timesheet_details_id` INNER JOIN `leads` AS `timesheet.lead` ON `timesheet.leads_id` = `timesheet.lead`.`id` AND `timesheet.lead`.`hiring_coordinator_id` = 326 LEFT OUTER JOIN `admin` AS `timesheet.lead.admin` ON `timesheet.lead`.`hiring_coordinator_id` = `timesheet.lead.admin`.`admin_id` LEFT OUTER JOIN `personal` AS `timesheet.personal` ON `timesheet.userid` = `timesheet.personal`.`userid` ORDER BY `timesheet_details`.`id` DESC;

Comme vous pouvez le voir, le LIMIT 0, 30 n'est pas à la fin de la requête. C'est un problème pour moi car cette requête ne retournera rien, et la limite et le décalage devraient être à la fin de la requête comme ceci:

SELECT `timesheet_details`.*, `timesheet_notes_subcons`.`note` AS `timesheet_notes_subcons.note`, `timesheet_notes_subcons`.`file_name` AS `timesheet_notes_subcons.file_name`, `timesheet_notes_subcons`.`id` AS `timesheet_notes_subcons.id`, `timesheet_notes_subcons`.`working_hrs` AS `timesheet_notes_subcons.working_hrs`, `timesheet_notes_subcons`.`timestamp` AS `timesheet_notes_subcons.timestamp`, `timesheet_notes_subcons`.`has_screenshot` AS `timesheet_notes_subcons.has_screenshot`, `timesheet_notes_subcons`.`notes_category` AS `timesheet_notes_subcons.notes_category`, `timesheet.lead`.`id` AS `timesheet.lead.id`, `timesheet.lead`.`fname` AS `timesheet.lead.fname`, `timesheet.lead`.`lname` AS `timesheet.lead.lname`, `timesheet.lead`.`email` AS `timesheet.lead.email`, `timesheet.lead`.`hiring_coordinator_id` AS `timesheet.lead.hiring_coordinator_id`, `timesheet.lead`.`status` AS `timesheet.lead.status`, `timesheet.lead.admin`.`admin_id` AS `timesheet.lead.admin.admin_id`, `timesheet.lead.admin`.`admin_fname` AS `timesheet.lead.admin.admin_fname`, `timesheet.lead.admin`.`admin_lname` AS `timesheet.lead.admin.admin_lname`, `timesheet.lead.admin`.`admin_email` AS `timesheet.lead.admin.admin_email`, `timesheet.lead.admin`.`signature_contact_nos` AS `timesheet.lead.admin.signature_contact_nos`, `timesheet.lead.admin`.`signature_company` AS `timesheet.lead.admin.signature_company`, `timesheet.personal`.`userid` AS `timesheet.personal.userid`, `timesheet.personal`.`fname` AS `timesheet.personal.fname`, `timesheet.personal`.`lname` AS `timesheet.personal.lname`, `timesheet.personal`.`email` AS `timesheet.personal.email` FROM (SELECT `timesheet_details`.`id`, `timesheet_details`.`timesheet_id`, `timesheet_details`.`day`, `timesheet_details`.`total_hrs`, `timesheet_details`.`adj_hrs`, `timesheet_details`.`regular_rostered`, `timesheet_details`.`hrs_charged_to_client`, `timesheet_details`.`diff_charged_to_client`, `timesheet_details`.`hrs_to_be_subcon`, `timesheet_details`.`diff_paid_vs_adj_hrs`, `timesheet_details`.`status`, `timesheet_details`.`reference_date`, `timesheet`.`id` AS `timesheet.id`, `timesheet`.`leads_id` AS `timesheet.leads_id`, `timesheet`.`userid` AS `timesheet.userid` FROM `timesheet_details` AS `timesheet_details` LEFT OUTER JOIN `timesheet` AS `timesheet` ON `timesheet_details`.`timesheet_id` = `timesheet`.`id` WHERE (`timesheet_details`.`reference_date` >= '2016-04-23 16:00:00' AND `timesheet_details`.`reference_date` < '2017-05-02 15:59:59') ORDER BY `timesheet_details`.`id` DESC) AS `timesheet_details` LEFT OUTER JOIN `timesheet_notes_subcon` AS `timesheet_notes_subcons` ON `timesheet_details`.`id` = `timesheet_notes_subcons`.`timesheet_details_id` INNER JOIN `leads` AS `timesheet.lead` ON `timesheet.leads_id` = `timesheet.lead`.`id` AND `timesheet.lead`.`hiring_coordinator_id` = 326 LEFT OUTER JOIN `admin` AS `timesheet.lead.admin` ON `timesheet.lead`.`hiring_coordinator_id` = `timesheet.lead.admin`.`admin_id` LEFT OUTER JOIN `personal` AS `timesheet.personal` ON `timesheet.userid` = `timesheet.personal`.`userid` ORDER BY `timesheet_details`.`id` DESC LIMIT 0, 30;

Y a-t-il quelque chose que je fais mal dans mon code? Ai-je égaré la commande et la limite?

13
Yassi

J'ai trouvé une réponse à ma question, il me suffit d'ajouter le subQuery = false afin que la limite et le décalage ne soient pas évalués dans la sous-requête. Et le décalage et la limite se trouvent également à la fin de la requête.

offset:((page-1)*limit),
limit : limit,
subQuery:false
13
Yassi

obtenu le même cas, une autre façon de le faire est de passer un tableau à limiter.

{
include: [
    {
        model: timesheetNotesSubcon,
        required: false,
        attributes:["note","file_name", "id", "working_hrs", "timestamp", "has_screenshot", "notes_category"]
    },
    {
        model: Timesheet,
        attributes:["id","leads_id","userid"],
        include:[
            {
                model: Lead_Info, attributes:["id","fname","lname","email","hiring_coordinator_id","status"],
                where: { hiring_coordinator_id : 326},
                include:[{
                    model: adminInfoSchema,
                    required: false,
                    attributes:["admin_id","admin_fname", "admin_lname", "admin_email", "signature_contact_nos", "signature_company"],      
                }]

            },
            {model:Personal_Info,attributes:["userid","fname","lname","email"]}
        ],
    }],
where: { 
    reference_date: filters.reference_date
},
order:[
    ["id","DESC"]
],
limit : [((page-1)*limit), limit],

}
1
Abdullah Shahin

Besoin de passer une commande et la clause where avant inclut.

 user.findAll({
             offset: 5, limit: 5,
            order: [
// Will escape full_name and validate DESC against a list of valid direction parameters
['full_name', 'DESC']]
        }).then(function (result) {
})

la requête résultante sera

enter image description here

si vous souhaitez placer la commande dans include, vous devez passer la commande dans include part

include: [{
                model: taskhelpers, required: true,
                order: {
                    order: '`updatedAt` ASC'
                }
           }]

pour une vérification plus détaillée Pagination/Limitation et commande

mise à jour inclus imbriqué et limite et ordre

var option = {
                offset: 5, limit: 5,
            order: [
// Will escape full_name and validate DESC against a list of valid direction parameters
['id', 'DESC']],
                attributes: [
                    'id', 'title',
                    [sequelize.Sequelize.fn('date_format', sequelize.Sequelize.col('date'), '%d-%b-%Y'), 'date']
                ],

                include: [

                    {
                        model: taskhelpers, required: true,

                        where: {
                            userId: req.params.userid,

                            $or: [
                                {
                                    status: {
                                        $eq: "1"
                                    }
                                },
                                {
                                    status: {
                                        $eq: "3"
                                    }
                                },
                            ]
                        }

                    }]
            };

passez maintenant cette option à votre paramètre de modèle

tasks.findAll(options)
    .then(function (result) {
        res.send({message:result,error:null});
    })
        .catch(function (err) {
            res.send({message:null,error:err});
        })

ce sera la requête générée

enter image description here

1
Adiii