在同一个表上使用COUNT()子查询插入MySQL
我在正确执行在同一个表上使用COUNT()子查询插入MySQL,mysql,insert,mysql-error-1093,Mysql,Insert,Mysql Error 1093,我在正确执行INSERT查询时遇到了问题,我似乎在Google或Stack Overflow上找不到任何解决此特定问题的方法 我试图为特色条目创建一个简单的表,其中条目id与当前顺序一起保存到表中 我想要的输出是: 如果功能表当前有以下三个条目: featured_id entry_id featured_order 1 27 0 2 54 1 4 23
INSERT
查询时遇到了问题,我似乎在Google或Stack Overflow上找不到任何解决此特定问题的方法
我试图为特色条目创建一个简单的表,其中条目id
与当前顺序一起保存到表中
我想要的输出是:
如果功能表当前有以下三个条目:
featured_id entry_id featured_order
1 27 0
2 54 1
4 23 2
我希望下一个条目保存为特色\u顺序
=3
我试图让以下查询在没有运气的情况下运行:
INSERT INTO `featured`
(
`entry_id`, `featured_order`
)
VALUES
(
200,
(SELECT COUNT(*) AS `the_count` FROM `featured`)
)
我得到的错误是:您不能在FROM子句中为更新指定目标表“featured”
有人能提供一个解决方案,在不引起错误的情况下获取计数吗
提前谢谢 这里有一件很酷的事情:MySQL的:
不需要子查询
@波希米亚人有一个很好的观点:
如果使用这种方法,最好使用max(特色订单)+1
因此,更好的查询可能是:
INSERT INTO `featured`
(
`entry_id`, `featured_order`
)
SELECT 200, MAX(`featured_order`) + 1
FROM `featured`
他在回答中描述的触发方法也是实现你想要的东西的好方法
查询1的潜在问题是,如果您删除一行,排名将被取消,并且您将在featured\u order
中有一个重复。对于第二个查询,这不是一个问题,但会有间隙,就像使用自动增量列一样
如果您绝对必须有一个没有间隙的订单,那么我知道的最佳解决方案是运行以下一系列查询:
SET @pos:=0;
DROP TABLE IF EXISTS temp1;
CREATE TEMPORARY TABLE temp1 LIKE featured;
ALTER TABLE featured ORDER BY featured_order ASC;
INSERT INTO temp1 (featured_id, entry_id, featured_order)
SELECT featured_id, entry_id, @pos:=@pos+1 FROM words;
UPDATE featured
JOIN temp1 ON featured.featured_id = temp1.featured_id
SET featured.rank = temp1.rank;
DROP TABLE temp1;
无论何时从相关子查询中删除行:
另一个限制是,当前无法修改表并从子查询中的同一表中进行选择
也许子查询中的别名或联接(否则没有用处)会有所帮助
编辑:原来有一个解决办法。解决方法如下所述。使用触发器:
drop trigger if exists featured_insert_trigger;
delimiter //
create trigger featured_insert_trigger before insert on featured
for each row
begin
set new.featured_order = ifnull((select max(featured_order) from featured), -1) + 1;
end; //
delimiter ;
现在插入的内容如下所示:
insert into featured (entry_id) values (200);
特色订单
将设置为最高特色订单值加1。这符合被删除/更新的行,并始终保证唯一性
如果表中没有行,则存在ifnull
,在这种情况下,第一个值将为零
此代码已经过测试,可以正常工作。您必须简单地使用alias来解决问题:
INSERT INTO `featured`
(
`entry_id`, `featured_order`
)
VALUES
(
200,
(SELECT COUNT(*) AS `the_count` FROM `featured` as f1)
)
更正只是添加“F1”表别名。(正如上面安吉林·纳达尔所建议的那样)
在多数据库环境中,这应该是更好的解决方案,因为相同的sintax在mysql+oracle+db2上运行良好
我还建议对以下方面进行改进:
- 选择计数(*)+1(问题:如果删除了一行,则会出现错误)
- 选择最大值(特征_顺序)+1(问题:第一行错误)
选择(合并(最大(特征顺序),0)+1)(没问题)可能重复而不是重复-该问题用于删除;这是用于插入的。这一点都不适用。我认为这行不通。从文档中的“但是,您不能插入到表中并在子查询中从同一个表中进行选择。”这方面的问题:a)您需要将一个添加到count(),b)如果编号与count()不一致怎么办-例如,如果行被删除。如果使用此选项,最好使用max(特色订单)+1approach@JIStone-我承认我没有试过。文档(这是5.5版的)看起来非常清晰。但是,这可能是错误的。您使用的是什么版本的MySQL?本例中的SELECT语句不被视为子查询。这很奇怪,因为关于子查询的警告出现在关于INSERT…SELECT的手册页面上(以及关于子查询语法的页面上)。这一“解决办法”涉及后续的更新语句-几乎不“优雅”“。我希望我没有暗示“优雅”:)如果在投票时提供解释会更好,这会很有帮助。我对触发因素做了一些研究(我以前从未听说过),这听起来绝对是最好的解决方案。然而,当我尝试它时,我得到了以下错误:TRIGGER命令拒绝给用户'xxxx'@'xxxx'表'featured'
我已经根据HostGator给MySQL用户“所有特权”,所以看起来这个项目的触发器不在卡中/如果在同一时间有两次插入,这是否有效?@xms“完全相同的时间”内不会发生任何更新/插入。数据库序列化所有变异查询。每个都是原子开始和完成的。我只是想知道。。。如果同时有两个插入件,这是否可以正常工作?
INSERT INTO `featured`
(
`entry_id`, `featured_order`
)
VALUES
(
200,
(SELECT COUNT(*) AS `the_count` FROM `featured` as f1)
)
INSERT INTO `featured`
(
`entry_id`, `featured_order`
)
VALUES
(
200,
(SELECT COUNT(*) AS `the_count` FROM `featured` F1)
)