我处于可以多次出现同一条记录的情况。
问题在于某些字段可能会丢失,这由该字段中的值-1表示。该字段的值将是正确的值或-1。正确的值将始终为正。问题是我事先不知道哪些字段会丢失,并且每条记录的丢失字段集可能不同。我的目标是在数据库中有一个最终条目,该条目汇集所有正确的值。
我想要做的是插入和替换那些值增加的列。鉴于唯一可能的值是-1并且正确的值是正数,这应确保我最终得到尽可能多的正确行(当然,可能从所有记录中省略了一些列。) / p>
conn = sqlite3.connect('example.db')
c = conn.cursor()
c.execute('''CREATE table IF NOT EXISTS SearchTable ([Owner] INTEGER
PRIMARY KEY, [Val1] INT, [Val2] INT)''')
c.execute("""INSERT OR REPLACE INTO SearchTable (Val1, Val2) values(-1,
5)""")
c.execute("""INSERT OR REPLACE INTO SearchTable (Owner, Val1, Val2)
values(1, 7, -1)""")
以上代码是我的尝试(我对sql还是很陌生),显然这是错误的,它会更新两个列,无论它们的当前值如何,但由于Val1已增加,因此它只应更新Val1,而Val2应该保持不变,因为它减少了。
以下问题似乎在询问类似问题,但在这种情况下,您有一个完整的数据集可与之进行比较,而您不知道在我的情况下哪些记录是完整的(如果有的话)。因此,我无法对此问题一概而论。
How to conditionally INSERT OR REPLACE a row in SQLite?
这个我真的根本听不懂答案,但是也许在解决我的问题时会有所帮助。
答案 0 :(得分:1)
我相信以下是您想做的事情。
如果您具有3.24.0或更高版本的SQlite,则可以使用 UPSERT (更新或插入)
例如:-
DROP TABLE IF EXISTS SearchTable;
CREATE TABLE IF NOT EXISTS SearchTable ([Owner] INTEGER PRIMARY KEY, [Val1] INT, [Val2] INT);
INSERT INTO SearchTable (Owner,Val1,Val2) VALUES(null,-1,5)
ON CONFLICT(Owner) DO UPDATE
SET
Val1 = CASE WHEN Val1 < 0 AND -1 /*<<<<<<<<<< value for val1 */ > 0 THEN -1 /*<<<<<<<<<< value for val1 */ ELSE Val1 END,
Val2 = CASE WHEN Val2 < 0 AND 5 /*<<<<<<<<<< value for val2 */ > 0 THEN 5 /*<<<<<<<<<< value for val2 */ ELSE Val2 END
;
INSERT INTO SearchTable (Owner,Val1,Val2) VALUES(1,7,-1)
ON CONFLICT(Owner) DO UPDATE
SET Val1 = CASE WHEN Val1 < 0 AND 7 /*<<<<<<<<< value for val1 */ > 0 THEN 7 /*<<<<<<<<<< value for val1 */ ELSE Val1 END,
Val2 = CASE WHEN Val2 < 0 AND 5 /*<<<<<<<<<<< value for val2 */ > 0 THEN 5 /*<<<<<<<<<< value for val2 */ ELSE Val2 END
;
结果:-
sqlite> INSERT INTO SearchTable (Owner,Val1,Val2) VALUES(null,-1,5) ON CONFLICT(Owner) DO UPDATE SET Val1 = CASE WHEN Val1 < 0 AND -1 > 0 THEN -1 ELSE Val1 END , Val2 = CASE WHEN Val2 < 0 AND 5 > 0 THEN 5 ELSE Val2 END;
sqlite> select * from SearchTable;
1|-1|5
sqlite> INSERT INTO SearchTable (Owner,Val1,Val2) VALUES(1,7,-1) ON CONFLICT(Owner) DO UPDATE SET Val1 = CASE WHEN Val1 < 0 AND 7 > 0 THEN 7 ELSE Val1 END, Val2 = CASE WHEN Val2 < 0 AND 5 > 0 THEN 5 ELSE Val2 END;
sqlite> select * from SearchTable;
1|7|5
如果SQlite版本低于3.24.0,请考虑:-
DROP TABLE IF EXISTS SearchTable;
CREATE TABLE IF NOT EXISTS SearchTable ([Owner] INTEGER PRIMARY KEY, [Val1] INT, [Val2] INT);
-- First Insert (null -1,5)
INSERT OR REPLACE INTO SearchTable ([Owner],Val1, Val2) VALUES(null /* owner null if first insert and auto generated value required, else known owner value */,
-- Handle VAL1 column
CASE
-- if no owner matching supplied value
WHEN (SELECT Val1 FROM SearchTable WHERE [owner] = null /*<<<<<<<<<< owner value */) IS NULL THEN -1 /* 1st value */
-- if current value is -1 then use supplied value
WHEN (SELECT Val1 FROM SearchTable WHERE [owner] = null /*<<<<<<<<< owner value */) = -1 THEN -1 /* 1st value */
-- if current value is o or greater then use current value
WHEN (SELECT Val1 FROM SearchTable WHERE [owner] = null /*<<<<<<<<< owner value */) > -1 THEN (SELECT Val1 FROM SearchTable WHERE [owner] = null /*<<<<<<<<<< owner value */)
END,
-- Handle Val2 Column
CASE
-- if no owner matching supplied value
WHEN (SELECT Val2 FROM SearchTable WHERE [owner] = null /*<<<<<<<<<< owner value */) IS NULL THEN 5 /* 2nd value */
-- if current value is -1 then use supplied value
WHEN (SELECT Val2 FROM SearchTable WHERE [owner] = null /*<<<<<<<<< owner value */) = -1 THEN 5 /* 2nd value */
-- if current value is 0 or greater then use current value
WHEN (SELECT Val2 FROM SearchTable WHERE [owner] = null /*<<<<<<<<< owner value */) > -1 THEN (SELECT Val2 FROM SearchTable WHERE [owner] = null /*<<<<<<<<<< owner value */)
END
);
-- Show result 1
SELECT * FROM SearchTable;
-- Second Insert (1,7,-1) !!!!Assumes that 5 should change to -1
INSERT OR REPLACE INTO SearchTable ([Owner],Val1, Val2) VALUES(1 /* owner null if first insert and auto generated value required, else known owner value */,
-- Handle VAL1 column
CASE
-- if no owner matching supplied value
WHEN (SELECT Val1 FROM SearchTable WHERE [owner] = 1 /*<<<<<<<<<< owner value */) IS NULL THEN 7 /* 1st value */
-- if current value is -1 then use supplied value
WHEN (SELECT Val1 FROM SearchTable WHERE [owner] = 1 /*<<<<<<<<< owner value */) = -1 THEN 7 /* 1st value */
-- if current value is 0 or greater then use current value
WHEN (SELECT Val1 FROM SearchTable WHERE [owner] = 1 /*<<<<<<<<< owner value */) > -1 THEN (SELECT Val1 FROM SearchTable WHERE [owner] = null /*<<<<<<<<<< owner value */)
END,
-- Handle Val2 Column
CASE
-- if no owner matching supplied value
WHEN (SELECT Val2 FROM SearchTable WHERE [owner] = 1 /*<<<<<<<<<< owner value */) IS NULL THEN -1 /* 2nd value */
-- if current value is -1 then use supplied value
WHEN (SELECT Val2 FROM SearchTable WHERE [owner] = 1 /*<<<<<<<<< owner value */) = -1 THEN -1 /* 2nd value */
-- if current value is 0 or greater then use current value
WHEN (SELECT Val2 FROM SearchTable WHERE [owner] = 1 /*<<<<<<<<< owner value */) > -1 THEN (SELECT Val2 FROM SearchTable WHERE [owner] = 1 /*<<<<<<<<<< owner value */)
END
);
-- Show result 2
SELECT * FROM SearchTable;
这最初使用3个提供的值([owner],val1和val1) null,-1和5 来添加行(所有者的值为null):-
第二种用法使用值([所有者],val1和val1) 1 , 7 和 -1
Val2未更新
我想要做的是插入和替换这些列 其价值增加了。假设唯一可能的值为-1 正确的值是正数,这应该确保我结束 尽可能多的正确行(当然可能是 删除所有记录中的某些列。)
按照:-