mariadb findOne与在连接表上findAll

pokxtpni  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(51)

我正试图将findAll函数改为findOne函数,因为我决定只需要一条记录。
但是,用于findAll的代码在更改为findOne时会导致错误。
我查看了sequelize生成的SQL查询,JOIN查询位置似乎有点偏离,使得查询无法发现连接的表。
我尝试了包含/排除原始数据:是的,但结果是一样的。
下面是findAll代码:

const member = await ManageMember.findAll({
  attributes: [
    ['id', 'memberIdx'],
    [Sequelize.col('manage_brand.id'), 'brandIdx'],
  ],
  include: [
    {
      model: ManageBrand,
      attributes: [],
      as: 'manage_brand',
    },
  ],
  where: {
    email: 'test@aaa.aaa',
  },
  raw: true,
});

生成的SQL查询:

SELECT `manage_member`.`id` AS `memberIdx`,
       `manage_brand`.`id`  AS `brandIdx`
FROM   `manage_member` AS `manage_member`
       LEFT OUTER JOIN `manage_brand` AS `manage_brand`
                    ON `manage_member`.`id` = `manage_brand`.`memberidx`
                       AND ( `manage_brand`.`deletedat` IS NULL )
WHERE  ( `manage_member`.`deletedat` IS NULL
         AND `manage_member`.`email` = 'test@aaa.aaa' );

查询结果:

[ { memberIdx: 29, brandIdx: 11 } ]

将findAll更改为findOne时产生的SQL查询:

SELECT `manage_member`.*
FROM   (SELECT `manage_member`.`id` AS `memberIdx`,
               `manage_brand`.`id`  AS `brandIdx`,
               `manage_member`.`id`
        FROM   `manage_member` AS `manage_member`
        WHERE  ( `manage_member`.`deletedat` IS NULL
                 AND `manage_member`.`email` = 'test@aaa.aaa' )
        LIMIT  1) AS `manage_member`
       LEFT OUTER JOIN `manage_brand` AS `manage_brand`
                    ON `manage_member`.`id` = `manage_brand`.`memberidx`
                       AND ( `manage_brand`.`deletedat` IS NULL );

执行查询时出错

Error
    at Query.run (/home/cnc4ever/pops_brand_back/node_modules/sequelize/lib/dialects/mysql/query.js:52:25)
    at /home/cnc4ever/pops_brand_back/node_modules/sequelize/lib/sequelize.js:314:28
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async MySQLQueryInterface.select (/home/cnc4ever/pops_brand_back/node_modules/sequelize/lib/dialects/abstract/query-interface.js:407:12)
    at async manage_member.findAll (/home/cnc4ever/pops_brand_back/node_modules/sequelize/lib/model.js:1134:21)
    at async manage_member.findOne (/home/cnc4ever/pops_brand_back/node_modules/sequelize/lib/model.js:1228:12)
    at async Object.wtf (/home/cnc4ever/pops_brand_back/src/auth/auth.repository.js:319:20)
    at async /home/cnc4ever/pops_brand_back/test.js:9:16 {
  name: 'SequelizeDatabaseError',
  parent: Error: Unknown column 'manage_brand.id' in 'field list'
      at Packet.asError (/home/cnc4ever/pops_brand_back/node_modules/mysql2/lib/packets/packet.js:728:17)
      at Query.execute (/home/cnc4ever/pops_brand_back/node_modules/mysql2/lib/commands/command.js:29:26)
      at Connection.handlePacket (/home/cnc4ever/pops_brand_back/node_modules/mysql2/lib/connection.js:456:32)
      at PacketParser.onPacket (/home/cnc4ever/pops_brand_back/node_modules/mysql2/lib/connection.js:85:12)
      at PacketParser.executeStart (/home/cnc4ever/pops_brand_back/node_modules/mysql2/lib/packet_parser.js:75:16)
      at Socket.<anonymous> (/home/cnc4ever/pops_brand_back/node_modules/mysql2/lib/connection.js:92:25)
      at Socket.emit (node:events:513:28)
      at addChunk (node:internal/streams/readable:324:12)
      at readableAddChunk (node:internal/streams/readable:297:9)
      at Readable.push (node:internal/streams/readable:234:10) {
    code: 'ER_BAD_FIELD_ERROR',
    errno: 1054,
    sqlState: '42S22',
    sqlMessage: "Unknown column 'manage_brand.id' in 'field list'",
    sql: "SELECT `manage_member`.* FROM (SELECT `manage_member`.`id` AS `memberIdx`, `manage_brand`.`id` AS `brandIdx`, `manage_member`.`id` FROM `manage_member` AS `manage_member` WHERE (`manage_member`.`deletedAt` IS NULL AND `manage_member`.`email` = 'test@aaa.aaa') LIMIT 1) AS `manage_member` LEFT OUTER JOIN `manage_brand` AS `manage_brand` ON `manage_member`.`id` = `manage_brand`.`memberIdx` AND (`manage_brand`.`deletedAt` IS NULL);",
    parameters: undefined
  },
  original: Error: Unknown column 'manage_brand.id' in 'field list'
      at Packet.asError (/home/cnc4ever/pops_brand_back/node_modules/mysql2/lib/packets/packet.js:728:17)
      at Query.execute (/home/cnc4ever/pops_brand_back/node_modules/mysql2/lib/commands/command.js:29:26)
      at Connection.handlePacket (/home/cnc4ever/pops_brand_back/node_modules/mysql2/lib/connection.js:456:32)
      at PacketParser.onPacket (/home/cnc4ever/pops_brand_back/node_modules/mysql2/lib/connection.js:85:12)
      at PacketParser.executeStart (/home/cnc4ever/pops_brand_back/node_modules/mysql2/lib/packet_parser.js:75:16)
      at Socket.<anonymous> (/home/cnc4ever/pops_brand_back/node_modules/mysql2/lib/connection.js:92:25)
      at Socket.emit (node:events:513:28)
      at addChunk (node:internal/streams/readable:324:12)
      at readableAddChunk (node:internal/streams/readable:297:9)
      at Readable.push (node:internal/streams/readable:234:10) {
    code: 'ER_BAD_FIELD_ERROR',
    errno: 1054,
    sqlState: '42S22',
    sqlMessage: "Unknown column 'manage_brand.id' in 'field list'",
    sql: "SELECT `manage_member`.* FROM (SELECT `manage_member`.`id` AS `memberIdx`, `manage_brand`.`id` AS `brandIdx`, `manage_member`.`id` FROM `manage_member` AS `manage_member` WHERE (`manage_member`.`deletedAt` IS NULL AND `manage_member`.`email` = 'test@aaa.aaa') LIMIT 1) AS `manage_member` LEFT OUTER JOIN `manage_brand` AS `manage_brand` ON `manage_member`.`id` = `manage_brand`.`memberIdx` AND (`manage_brand`.`deletedAt` IS NULL);",
    parameters: undefined
  },
  sql: "SELECT `manage_member`.* FROM (SELECT `manage_member`.`id` AS `memberIdx`, `manage_brand`.`id` AS `brandIdx`, `manage_member`.`id` FROM `manage_member` AS `manage_member` WHERE (`manage_member`.`deletedAt` IS NULL AND `manage_member`.`email` = 'test@aaa.aaa') LIMIT 1) AS `manage_member` LEFT OUTER JOIN `manage_brand` AS `manage_brand` ON `manage_member`.`id` = `manage_brand`.`memberIdx` AND (`manage_brand`.`deletedAt` IS NULL);",
  parameters: {}
}

我最接近于让它工作的方法是,在include部分添加属性,并注解掉属性部分中的Sequelize.col部分。它工作,但我需要别名它,但别名它将导致同样的上述错误。
这一工作原理:

const member = await ManageMember.findOne({
  attributes: [
    ['id', 'memberIdx'],
    // [Sequelize.col('manage_brand.id'), 'brandIdx'],
  ],
  include: [
    {
      model: ManageBrand,
      attributes: ['id'],
      as: 'manage_brand',
    },
  ],
  where: {
    email: 'test@aaa.aaa',
  },
  raw: true,
});

查询:

SELECT `manage_member`.*,
       `manage_brand`.`id` AS `manage_brand.id`
FROM   (SELECT `manage_member`.`id` AS `memberIdx`,
               `manage_member`.`id`
        FROM   `manage_member` AS `manage_member`
        WHERE  ( `manage_member`.`deletedat` IS NULL
                 AND `manage_member`.`email` = 'test@aaa.aaa' )
        LIMIT  1) AS `manage_member`
       LEFT OUTER JOIN `manage_brand` AS `manage_brand`
                    ON `manage_member`.`id` = `manage_brand`.`memberidx`
                       AND ( `manage_brand`.`deletedat` IS NULL );

导致:

{ memberIdx: 29, id: 29, 'manage_brand.id': 11 }

这是否按预期工作?还是我做错了什么
为了记录,我使用续集6.25.5,非常感谢!

oyjwcjzk

oyjwcjzk1#

感谢@emma的评论,我能够解决这个问题。
通过添加subQuery:false,则查询结果为:

SELECT `manage_member`.`id` AS `memberIdx`,
       `manage_brand`.`id`  AS `brandIdx`
FROM   `manage_member` AS `manage_member`
       LEFT OUTER JOIN `manage_brand` AS `manage_brand`
                    ON `manage_member`.`id` = `manage_brand`.`memberidx`
                       AND ( `manage_brand`.`deletedat` IS NULL )
WHERE  ( `manage_member`.`deletedat` IS NULL
         AND `manage_member`.`email` = 'test@aaa.aaa' )
LIMIT  1

在findAll查询的末尾添加LIMIT 1。仍然认为这是一个奇怪的行为,但在续集的乡亲似乎意识到这一点。
再次感谢你@艾玛!!

相关问题