我无法正常执行INSERT
查询,而且我似乎无法在Google或Stack Overflow上找到解决此特定问题的任何内容。
我正在尝试为特色条目创建一个简单的表格,其中entry_id
与其当前顺序一起保存到表格中。
我想要的输出是:
如果featured
表目前有这三个条目:
featured_id entry_id featured_order
1 27 0
2 54 1
4 23 2
我想要使用featured_order
= 3保存下一个条目。
我正试图让以下查询无效运行:
INSERT INTO `featured`
(
`entry_id`, `featured_order`
)
VALUES
(
200,
(SELECT COUNT(*) AS `the_count` FROM `featured`)
)
我得到的错误是:You can't specify target table 'featured' for update in FROM clause
。
任何人都可以帮助获得计数而不会导致错误的解决方案吗?
提前致谢!
答案 0 :(得分:14)
这是一件很酷的事:MySQL的INSERT . . . SELECT
:
INSERT INTO `featured`
(
`entry_id`, `featured_order`
)
SELECT 200, COUNT(*) + 1
FROM `featured`
不需要子查询。
@Bohemian有一个好点:
如果使用此方法,最好使用max(featured_order)+ 1
所以更好的查询可能是:
INSERT INTO `featured`
(
`entry_id`, `featured_order`
)
SELECT 200, MAX(`featured_order`) + 1
FROM `featured`
他的触发方法在他的回答中描述也是实现你想要的好方法。
查询1的潜在问题是,如果您删除了一行,则排名将被删除,并且您将在featured_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;
每当删除一行时
答案 1 :(得分:2)
使用触发器:
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);
featured_order
将设置为最高的featured_order值加1。这适用于删除/更新的行,并始终保证唯一性。
如果表中没有行,ifnull
就存在,在这种情况下,第一个值将为零。
此代码已经过测试,可以正常使用。
答案 2 :(得分:2)
INSERT INTO `featured`
(
`entry_id`, `featured_order`
)
VALUES
(
200,
(SELECT COUNT(*) AS `the_count` FROM `featured` F1)
)
更正只是添加“F1”表别名。 (正如上面的Angelin Nadar所建议的那样)
这应该是多数据库环境中更好的解决方案,因为相同的sintax在mysql + oracle + db2上工作正常
我还建议改进:
SELECT COUNT(*)+1(问题:如果某行被删除则会出错)
SELECT MAX(featured_order)+1(问题:第一行错误)
SELECT(COALESCE(MAX(featured_order),0)+1)(没问题)
答案 3 :(得分:1)
您必须使用能够解决问题的别名:
INSERT INTO `featured`
(
`entry_id`, `featured_order`
)
VALUES
(
200,
(SELECT COUNT(*) AS `the_count` FROM `featured` as f1)
)
答案 4 :(得分:-1)
关于子查询的MySQL manual:
另一个限制是,目前您无法修改表并从子查询中的同一个表中进行选择。
子查询中的别名或连接(否则无用)可能对此有所帮助。
编辑:事实证明,有一种解决方法。该变通方法被描述为http://www.xaprb.com/blog/2006/06/23/how-to-select-from-an-update-target-in-mysql/。