将SQL查询转换为具有多个表的顺序查询

时间:2019-07-14 01:29:57

标签: mysql node.js sequelize.js

我已经花了几天的时间试图将我认为是相对简单的SQL查询转换为sequelize格式。我似乎无法弄清楚我的一生。我是新手,我的SQL技能也可以使用一些帮助。

非常感谢您的帮助!

这是我遇到的SQL查询(该查询可用于我要执行的操作),我正在努力使其能够连续工作:

    SELECT 
        book.id,
        book.author,
        book.title,
        book_type.type,
        book_sub_type.sub_type,
        book_location.location,
        book_language.language
    FROM book
    INNER JOIN book_type ON book.book_type_id = book_type.id
    INNER JOIN book_sub_type ON book.book_sub_type_id = book_sub_type.id
    INNER JOIN book_location ON book.book_location_id = book_location.id
    INNER JOIN book_language ON book.book_language_id = book_language.id
    WHERE
        book.author LIKE '%history%' OR
        book.title LIKE '%history%' OR
        book_type.type LIKE '%history%' OR
        book_sub_type.sub_type LIKE '%history%' OR
        book_language.language LIKE '%history%' OR
        book_location.location LIKE '%history%'
    ORDER BY book_type.type, book_sub_type.sub_type;

据我所知(此连续查询返回0个结果,因为它正在所有列而不是至少一列中搜索子字符串“ history”):

    const books = await Book.findAll({
        where: {
            [Op.or]: [
                {author: { [Op.substring]: 'history' }},
                {title: { [Op.substring]: 'history' }}
            ]
        },
        attributes: ['id', 'author', 'title'],
        include: [
            { 
                model: BookType, 
                attributes: ['type'], 
                where: {
                    type: { [Op.substring]: 'history' }
                } 
            },
            { 
                model: BookSubType, 
                attributes: ['sub_type'], 
                where: {
                    sub_type: { [Op.substring]: 'history' }
                } 
            },
            { 
                model: BookLanguage, 
                attributes: ['language'], 
                where: {
                    language: { [Op.substring]: 'history' }
                } 
            },
            { 
                model: BookLocation, 
                attributes: ['location'], 
                where: {
                    location: { [Op.substring]: 'history' }
                }  
            },
        ]
    });

我的架构如下:

`book` table columns:
`id`, `author`, `title`, `book_type_id`, `book_sub_type_id`, 
`book_language_id`, `book_location_id`

`book_type` table columns:
`id`, `type`

`book_sub_type` table columns:
`id`, `sub_type`

`book_location` table columns:
`id`, `location`

`book_language` table columns:
`id`, `language`

在续篇中,我建立了以下关系:

    Book.belongsTo(BookType);
    Book.belongsTo(BookSubType);
    Book.belongsTo(BookLanguage);
    Book.belongsTo(BookLocation);
    BookType.hasMany(Book);
    BookSubType.hasMany(Book);
    BookLanguage.hasMany(Book);
    BookLocation.hasMany(Book);

输出应为7列: book.id,book.author,book.title,book_type.type,book_sub_type.sub_type,book_location.location,book_language.language

1 个答案:

答案 0 :(得分:1)

Sequelize使用JOIN中的条件构建SQL,因此这不是一个好方法。您应从包含中删除所有where个条件。在续集<4.0.0中,有一种方法可以使用语法

将条件写入子查询
 where: {
      $or: [{
        '$book.sub_type$$': 'history'
      }, {
        '$book_type.type$': 'history'
      }]
 } 

但是我认为这不再受支持。唯一的方法是自定义查询或在where对象中使用序列化文字。

where: {
     [Op.or]: [{
         Sequelize.literal(`book_type.type LIKE ${history}`)
     }, {
         Sequelize.literal(`book_sub_type.sub_type LIKE ${history}`)
     }]
}

请记住,使用这种方法存在SQL注入的风险,因此您应该验证输入或使用一些转义字符策略。选中sequelize raw queriesseqeulize literal