在同一个表上使用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)
)