如果还没有具有相同 id 和 url(两列值)的行,则插入行
Insert row if there isn't already a row with the same id and url (two column values)
我想编写一个 SQL 语句,在数据库中没有一行的情况下向数据库中插入一个新行。一行的唯一标识符是id和url。假设 table 架构如下所示:
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);
我想你想要这样的东西:
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);
您可以在 id
和 url
列上添加唯一索引:
ALTER TABLE LinkClicks ADD UNIQUE u_idx (id, url);
有了这个约束,尝试插入一条已经出现 id
和 url
值组合的记录将在数据库级别失败。
这可能比您正在尝试的查询更可取,因为它保证 MySQL 将拒绝重复的插入尝试。查询也可以用于此效果,但稍后使用您的代码库的其他人可能会忘记这一点。
事实上,您应该采纳 Tim 的建议,将唯一索引放在 table 上,但在这样做时,您需要一种故障安全的方法来确保您不会尝试放置重复项(id 和 url) 到 table 中(否则会出现大量红色墨水消息)。这样看来还可以:
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 组合与目标 table 中已有行不同的那些行。它非常乐意插入 ID 相同但 URL 不同或 ID 不同但 URL 相同的行。
我唯一的保留意见是来源 table 中 'dupes' 的问题(在本例中为 LINKCLICKS1)。如果源 table 中有重复项,其中 none 将被插入到目标 table 中。这将打败查询对象。
答案是,如果您有重复项,或者在源 table 中有任何重复的风险,那么您应该在 [=34] 之前将 'de-dupe code' 应用到源 table =] 这个.
如果您需要任何重复数据删除代码,请在下面发表评论。
我想编写一个 SQL 语句,在数据库中没有一行的情况下向数据库中插入一个新行。一行的唯一标识符是id和url。假设 table 架构如下所示:
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);
我想你想要这样的东西:
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);
您可以在 id
和 url
列上添加唯一索引:
ALTER TABLE LinkClicks ADD UNIQUE u_idx (id, url);
有了这个约束,尝试插入一条已经出现 id
和 url
值组合的记录将在数据库级别失败。
这可能比您正在尝试的查询更可取,因为它保证 MySQL 将拒绝重复的插入尝试。查询也可以用于此效果,但稍后使用您的代码库的其他人可能会忘记这一点。
事实上,您应该采纳 Tim 的建议,将唯一索引放在 table 上,但在这样做时,您需要一种故障安全的方法来确保您不会尝试放置重复项(id 和 url) 到 table 中(否则会出现大量红色墨水消息)。这样看来还可以:
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 组合与目标 table 中已有行不同的那些行。它非常乐意插入 ID 相同但 URL 不同或 ID 不同但 URL 相同的行。
我唯一的保留意见是来源 table 中 'dupes' 的问题(在本例中为 LINKCLICKS1)。如果源 table 中有重复项,其中 none 将被插入到目标 table 中。这将打败查询对象。
答案是,如果您有重复项,或者在源 table 中有任何重复的风险,那么您应该在 [=34] 之前将 'de-dupe code' 应用到源 table =] 这个.
如果您需要任何重复数据删除代码,请在下面发表评论。