我有一张桌子
'images'
,如下所示:
产品ID | 排序 | 来源 |
---|---|---|
1 | 1 |
|
1 | 2 |
|
2 | 1 |
|
2 | 2 |
|
2 | 3 |
|
在一个 mysql 查询中,我想插入多行。但是,最重要的是,我想填充每一行的下一个
SortOrder
(从最后一行开始ProductId
)。
例如,我希望能够做到:
const values = [
[2,'source.com/456546', @max_sort_order := @max_sort_order + 1],
[2,'source.com/237675', @max_sort_order := @max_sort_order + 1]
]
const query = "SET @max_sort_order := (SELECT COALESCE(MAX( SortOrder ), 1) FROM images i WHERE ProductId = 2);INSERT INTO images (ProductId, Source, SortOrder) VALUES ?"
connection.query({sql: query, timeout: 40000, values: [values]...
理想情况下会产生以下新行:
产品ID | 排序 | 来源 |
---|---|---|
2 | 4 |
|
2 | 5 |
|
但是我不能将
@max_sort_order
变量放入值中,因为它是准备好的值(我认为)。
关于如何解决这个问题有什么想法吗?
您必须在 JavaScript 中执行逻辑,而不是 MySQL。
您可以通过一次调用获得所有产品 ID 的
MAX(SortOrder)
。然后,您可以填写 SortOrder
数组中递增的 values
字段,并对所有字段进行批量插入。
const values = [
[2,'source.com/456546', 0],
[2,'source.com/237675', 0]
];
// Create object whose keys are the unique ProductID values.
const pidMap = Object.fromEntries(values.map(([pid]) => [pid, 0]));
const unique_pids = Object.keys(pidMap);
const placeholders = unique_pids.map(_ => '?').join(',');
const max_query = `SELECT ProductID, MAX(SortOrder) FROM images WHERE ProductID IN (${placeholders}) GROUP BY ProductID`;
connection.query(max_query, unique_pids, function(err, result) {
if (error) {
throw error;
}
// Fill in the values of the object
result.foreach(([pid, max]) => pidMap[pid] = max);
// Update the SortOrder fields in the values array with incrementing numbers
values.forEach(val => val[2] = pidMap[++val[0]]);
connection.query('INSERT INTO images (ProductID, Source, SortOrder) VALUES ?', values, function(err, result) { ... });
});