SQlite Вставить или заменить условно, если значение каждого столбца больше его текущего значения. - PullRequest
0 голосов
/ 10 июля 2019

Я в ситуации, когда одна и та же запись может появляться несколько раз.

Беда в том, что некоторые поля могут отсутствовать, это обозначается значением -1 в этом поле,Значение поля будет либо правильным значением, либо -1.Правильное значение всегда будет положительным.Проблема в том, что я не знаю заранее, какие поля будут отсутствовать, и набор пропущенных полей может быть разным для каждой записи.Моя цель - иметь окончательную запись в базе данных, которая объединяет все правильные значения.

Что я хочу сделать, это вставить и заменить те столбцы, значение которых увеличилось.Учитывая, что единственными возможными значениями являются -1 и правильное значение, которое является положительным, это должно гарантировать, что я получу как можно больше правильных строк (возможно, конечно, что некоторые столбцы опущены во всех записях.)

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 должен остаться неизменным, потому что он уменьшился.

В приведенном ниже вопросе, похоже, задается вопрос о чем-то подобном, но в этом случае у вас есть полный набор данных для сравнения, вы не знаете, с каким (если он есть) изrecs завершены в моем случае.Так что я не смог обобщить это решение для моей проблемы.

Как условно вставить или заменить строку в SQLite?

Этого я действительно не могпонять ответ вообще, но, возможно, он поможет вам при попытке решить мою проблему.

Условная вставка или замена SQLite

1 Ответ

1 голос
/ 11 июля 2019

Я считаю, что следующее соответствует тому, что вы хотите сделать.

Если у вас SQlite версии 3.24.0 или выше, вы можете использовать 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 предоставленных значения ([владелец], val1 и val1) ноль, -1 и 5 согласно: -

enter image description here

Второе использование изменяет строку, используя значения ([owner], val1 и val1) 1 , 7 и -1

  • Val2 не обновляется согласно моей интерпретации: -

    • Что я хочу сделать, это вставить и заменить эти столбцы чья ценность увеличилась. Учитывая, что единственно возможными значениями являются -1 и правильное значение, которое является положительным, это должно гарантировать, что я заканчиваю с как можно большим количеством правильных строк (это может быть, конечно, что некоторые столбцы опущены во всех записях.)

Согласно: -

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...