我有一个表links
,其中包含列id,url,url_hash和parent_id(还有更多与我的问题无关)。我的代码中有2个变量,$ url和$ parentUrl,它们可能引用links
表中的现有行。所以我想将parent_id设置为其url与$ parentUrl匹配的第一个链接的id,或者将其设置为0,如果没有父级,则设置为null。
INSERT INTO `links` (`url`, `url_hash`, `parent_id`)
SELECT $url, MD5(url), `id`
FROM `links`
WHERE `url` = $parentUrl
LIMIT 1
但是如果select语句返回0行,则会失败。我希望我的查询只是根据const值(url,url_hash)插入一个新行。
INSERT INTO `links` (`url`, `url_hash`, `parent_id`)
VALUES ($url, MD5(url), ((SELECT `id` FROM `links` WHERE `url`=$parentUrl LIMIT 1))
也试过这个,但这似乎失败了这个错误:
You can't specify target table 'links' for update in FROM clause
我这样做是为了避免使用两个查询的当前工作解决方案。甚至可以在一个查询中使用吗?
答案 0 :(得分:1)
当你需要一排时 - 即使没有匹配 - 想想聚合。在你的情况下:
INSERT INTO `links` (`url`, `url_hash`, `parent_id`)
SELECT $url, MD5($url), max(id)
FROM (SELECT id
FROM `links`
WHERE `url` = $parentUrl
LIMIT 1
) t;
这将生成一行。我不确定在这种情况下“第一”意味着什么。这将是一个任意行。您需要order by
才能获得特定订单。
我也猜测表达式MD5(url)
应该是MD5($url)
。
编辑:
并不是说它确实有很大的不同,但如果您只想引用$url
一次:
INSERT INTO `links` (`url`, `url_hash`, `parent_id`)
SELECT url, MD5(url), max(id)
FROM (SELECT id, $url as url
FROM `links`
WHERE `url` = $parentUrl
LIMIT 1
) t;