我有以下INSERT
INSERT INTO `tbl_productcategorylink`
(`pcl_p_id`, `pcl_cat_id`, `pcl_orderby`)
SELECT
`p_id` AS pcl_p_id,
(SELECT `cat_id` FROM `tbl_categories` WHERE
CASE
WHEN `tbl_products`.`p_gender` = 'female' THEN
`cat_url_tag` = 'womens'
ELSE
`cat_url_tag` = 'mens'
END
LIMIT 1) AS pcl_cat_id,
1 AS pcl_orderby
FROM `tbl_products`
WHERE `tbl_products`.`p_gender` = 'female' OR `tbl_products`.`p_gender` = 'male';
这是为了在类别和产品之间添加链接,将p_gender
设置为“男性”的任何产品都添加到“男性”类别,类似地添加到“女性”类别。
如果给定产品的行还不存在,我该怎么做呢?
我基本上需要在WHERE
子句中添加一些内容来确定行是否已存在:
AND `exists` IS NULL
我试图在查询的exists
部分创建此SELECT
列,但这会使列数混乱并导致INSERT
失败。
有任何建议要实现这个目标吗?
感谢。
答案 0 :(得分:3)
INSERT
tbl_productcategorylink
(pcl_p_id, pcl_cat_id, pcl_orderby)
SELECT
p.p_id, c.cat_id, 1
FROM
tbl_products p
INNER JOIN tbl_categories c ON c.cat_url_tag = CASE p.p_gender
WHEN 'female' THEN 'womens'
ELSE 'mens' END
WHERE
p.p_gender IN ('female', 'male')
AND NOT EXISTS (
SELECT 1 FROM tbl_productcategorylink WHERE pcl_p_id = p.p_id
)
答案 1 :(得分:1)
在WHERE子句中尝试NOT EXISTS:
INSERT INTO `tbl_productcategorylink`
(`pcl_p_id`, `pcl_cat_id`, `pcl_orderby`)
SELECT
`p_id` AS pcl_p_id,
(SELECT `cat_id` FROM `tbl_categories` WHERE
CASE
WHEN `tbl_products`.`p_gender` = 'female' THEN
`cat_url_tag` = 'womens'
ELSE
`cat_url_tag` = 'mens'
END
LIMIT 1) AS pcl_cat_id,
1 AS pcl_orderby
FROM `tbl_products`
WHERE `tbl_products`.`p_gender` = 'female' OR `tbl_products`.`p_gender` = 'male'
AND NOT EXISTS (SELECT * FROM `tbl_productcategorylink` WHERE `pcl_p_id` = `tbl_products`.`p_id`);
答案 2 :(得分:1)
如果密钥存在,您可以使用INSERT IGNORE
继续。假设列上有唯一键。
答案 3 :(得分:0)
“插入忽略”在以后重新执行相同的SQL时效率不高,因为它将尝试重新插入所有记录。为了获得最佳系统性能,您必须将插入次数限制为尽可能少的数量。
使用子选择查询也是低效的,在使用大型数据集时,“LEFT JOIN”几乎总是更快。子选择查询在SELECT子句中变得很糟糕。在LEFT JOINed表中的字段周围的SELECT子句中使用'IFNULL()',为缺失/ NULL记录提供默认值。
Tomalak的答案有效,但这里有一个纯粹的“LEFT JOIN”示例。
INSERT INTO tbl_productcategorylink (p_pid, pcl_cat_id, pcl_orderby )
SELECT prod.p_pid, IFNULL( cat.cat_id,0 ), 1 AS pcl_orderby
FROM tbl_products AS prod
LEFT JOIN tbl_categories AS cat ON cat.cat_url_tag = IF(prod.p_gender='female','womans','mens')
LEFT JOIN tbl_productcategorylink AS pcl ON pcl.pcl_p_id = prod.p_id
WHERE prod.p_gender IN ('female','male')
AND pcl.pcl_p_id IS NULL -- Optimizes to faster "NOT EXISTS IN (Select ... From pcl )"
这次重写假设tbl_categories有2个特定记录:'womans'和'mens'。 请注意'where'子句包含“pcl_p_pid IS NULL”,当处理非常大的数据集时,它会优化为“NOT EXISTS IN(Select * From tbl_productcategorylink ...)”的更快版本。
子选择查询执行以下两项操作之一:
a)创建一个临时表
b)当数据库遍历主要的“From”表时,对可能存在的EACH记录的子选择表执行“查找”。当子选择在'SELECT'子句中时,这被夸大为可怕的性能。
LEFT JOIN使用数据库提供的已经高效的JOIN逻辑,允许丢失记录。
- J Jorgenson -