如果还没有一行具有相同的id和url(两列值),请插入行

时间:2017-10-25 02:08:26

标签: mysql sql-server insert notin

我想写一个SQL语句,如果没有一行就会在数据库中插入新行。行的唯一标识符是id和url。假设表模式如下所示:

LinkClicks: (id, url, clicks)

现在让我们说我有一个带参数化SQL插入的行。我试图做这样的事情:

INSERT (id, url, clicks) 
INTO LinkClicks Values(@id, @url, @clicks) 
WHERE @url NOT IN 
    (SELECT url FROM LinkClicks WHERE id=@id);

3 个答案:

答案 0 :(得分:1)

我想你想要这样的东西:

INSERT INTO LinkClicks(id, url, clicks)
    SELECT id, url, clicks
    FROM (SELECT @id as id, @url as url, @clicks as clicks) t
    WHERE t.url NOT IN (SELECT url FROM LinkClicks WHERE id = @id);

答案 1 :(得分:1)

您可以在idurl列添加唯一索引:

ALTER TABLE LinkClicks ADD UNIQUE u_idx (id, url);

有了这个约束,尝试插入已经出现idurl值组合的记录将在数据库级别失败。

这可能比您正在尝试的查询更可取,因为它可以保证MySQL将拒绝重复的插入尝试。查询也可以用于此效果,但稍后可能使用您的代码库的其他人可能会忘记这一点。

答案 2 :(得分:0)

事实上你应该接受Tim的建议,并在表上放置唯一索引,但这样做需要一种确保不会尝试将重复项(id和url)放入表中的故障安全方法(否则加载红墨水信息)。这种方式似乎没问题:

DROP TABLE LINKCLICKS
DROP TABLE LINKCLICKS1

CREATE TABLE LINKCLICKS
(
[ID] INT,
[URL] CHAR(11),
CLICKS BIGINT
)
GO
INSERT INTO LINKCLICKS VALUES (1001,'www.abc.com',40000)
INSERT INTO LINKCLICKS VALUES (1002,'www.def.com',40000)
INSERT INTO LINKCLICKS VALUES (1003,'www.ghi.com',40000)
GO

CREATE TABLE LINKCLICKS1
(
[ID] INT,
[URL] CHAR(11),
CLICKS BIGINT
)
GO
INSERT INTO LINKCLICKS1 VALUES (1001,'www.abc.com',40000)
INSERT INTO LINKCLICKS1 VALUES (1003,'www.def.com',40000)
INSERT INTO LINKCLICKS1 VALUES (1004,'www.ghi.com',40000)
GO

WITH CTE1 AS
(
SELECT *,'d' AS [Source] FROM LINKCLICKS
UNION ALL
SELECT *,'s' AS [Source] FROM LINKCLICKS1
)
,
CTE2 AS
(
SELECT ID,[URL] FROM CTE1 GROUP BY ID,[URL] HAVING COUNT(ID) =1 AND COUNT([URL]) =1
)
INSERT INTO LINKCLICKS
SELECT ID,[URL],CLICKS 
FROM CTE1 
WHERE [Source] <> 'd' 
AND 
(
ID IN (SELECT ID FROM CTE2) AND [URL] IN (SELECT [URL] FROM CTE2)
)

SELECT * FROM LINKCLICKS ORDER BY [ID],URL
GO

INSERT语句仅插入ID和URL组合的行与目标表中已有的行不同。很高兴地插入行ID,其中ID相同但URL不同或ID不同但URL相同。

我唯一的保留是源表中的'dupes'问题(在本例中为LINKCLICKS1)。如果源表中存在重复项,则它们都不会插入到目标表中。这将打败查询的对象。

答案是,如果您在源表中有重复项或任何重复风险,那么您应该在运行此表之前将“重复数据删除代码”应用于源表。

如果您需要任何重复数据删除代码,请在下方发表评论。