SQL INSERT 但如果存在则增加 ID 而无需执行单独的 SELECT 查询

问题描述 投票:0回答:2

我有一个表,主键在两列上:

ID
(用户 ID)和
SQ
(序列,从 1 开始,每个
ID
递增 +1)。一个用户不应该有相同序列号的多个实例。这是表格的样子:

ID      SQ    Code
------  --    ----
123456  1     123
654321  1     369
123456  2     234

我正在尝试在

Code
列中插入一个值,但在我这样做之前,我需要检查特定用户是否已经拥有该代码,如果是,请接收序列号。

目前,我运行:

# CodeExists is 1 if user has code already. 0 otherwise
# Max_SQ gives the maximum SQ that exists for this user
cursor.execute("SELECT MAX(CASE WHEN Code = ? THEN 1 ELSE 0 END) AS 'CodeExists', MAX(SQ) AS 'Max_SQ' FROM TABLENAME WHERE ID = ? GROUP BY ID", Code, User_PID)
data = cursor.fetchone()
if data is None: # This user does not have any codes, SQ starts at 1
    SQ = 1
else:
    CodeExists, SQ = data # Unpack query values
    if int(CodeExists) == 1: # User already has the code we are trying to insert, skip
        continue
    else:
        SQ = int(SQ) + 1 # Increment SQ
cursor.execute("INSERT INTO TABLENAME (ID,SQ,Code) VALUES(?,?,?)", User_PID, SQ, Code)
cursor.commit()

例子:

  • 尝试为用户 =123456 插入代码 =123,不应插入。该用户已有代码 123。
  • 尝试为用户 =654321 插入代码 =123,应该使用 SQ=2 插入
  • 尝试为用户=999999 插入代码=123,应该插入 SQ=1

给定代码 # 和用户 ID,有没有办法将其组合成单个 INSERT 查询?

python sql sql-server sql-insert
2个回答
1
投票

使用 CTE 存储新行的

ID
Code

然后将 CTE
LEFT
连接到表并聚合以获得该
SQ
的最大
ID
并将其增加 1.
HAVING
子句中设置条件,如果表中已经有一行代码与 CTE 中的代码相同,则查询不应返回要插入的任何行。

这是查询:

WITH cte AS (SELECT * FROM (VALUES (123456, 123))t (ID, Code))
INSERT INTO tablename (ID, SQ, Code)
SELECT c.ID,
       COALESCE(MAX(t.SQ), 0) + 1,
       c.Code
FROM cte c LEFT JOIN tablename t
ON t.ID = c.ID 
GROUP BY c.ID, c.Code
HAVING MAX(CASE WHEN c.Code = t.Code THEN 1 END) IS NULL;

查看演示


1
投票

在 MysQL 中你可以这样做

CREATE TABLE TABLENAME
    (`ID` int, `SQ` int, `Code` int)
;
    
INSERT INTO TABLENAME
    (`ID`, `SQ`, `Code`)
VALUES
    (123456, 1, 123),
    (654321, 1, 369),
    (123456, 2, 234)
;

INSERT INTO TABLENAME (ID,SQ,Code) 
SELECT 1223344,( SELECT COALESCE(MAX(SQ),0) +1 FROM TABLENAME  WHERE ID =  1223344) ,666 
WHERE  NOT EXISTS ( SELECT 1 FROM TABLENAME  WHERE ID =  1223344 AND Code = 666)
Records: 1  Duplicates: 0  Warnings: 0
INSERT INTO TABLENAME (ID,SQ,Code) 
SELECT 123456,( SELECT COALESCE(MAX(SQ),0) +1 FROM TABLENAME  WHERE ID =  123456) ,666 
WHERE  NOT EXISTS( SELECT 1 FROM TABLENAME  WHERE ID =  123456 AND Code = 666)
Records: 1  Duplicates: 0  Warnings: 0
INSERT INTO TABLENAME (ID,SQ,Code) 
SELECT 1223344,( SELECT COALESCE(MAX(SQ),0) +1 FROM TABLENAME  WHERE ID =  1223344) ,666 
WHERE  NOT EXISTS( SELECT 1 FROM TABLENAME  WHERE ID =  1223344 AND Code = 666)
Records: 0  Duplicates: 0  Warnings: 0
SELECT * FROM TABLENAME
ID 平方 代码
123456 1 123
654321 1 369
123456 2 234
1223344 1 666
123456 3 666

小提琴

© www.soinside.com 2019 - 2024. All rights reserved.