在我的iOS和Android项目中,我有一个看起来像这样的SQLite表:
id words
-----------
1 apple, banana, orange, peach, strawberry
2 car, plane, orange
3 sheep, car, plane, horse, cow
. ...
.
.
words
列是TEXT
列,其中包含以逗号分隔的单词列表。
我想通过在列表的前面添加一个单词来更新特定行的单词列表。该列表不应超过5个项目,因此如有必要,我也会删除最后一个单词。
例如,如果我使用row id 1
更新cherry
,那么我会得到
cherry, apple, banana, orange, peach
或者如果我在row id 2
上进行相同的更新,那么我会得到
cherry, car, plane, orange
我的问题
我知道我可以进行查询以获取行,处理文本,然后更新行。但是,这需要两个表查找,一个用于查询,另一个用于更新。这可能与单个更新查找有关吗?
我知道有replace() function,但我不会在这里替换任何东西。我也不仅仅是incrementing an integer。我在SQLite core functions中没有看到任何明显的东西。
答案 0 :(得分:3)
The words column is a TEXT column that holds a comma deliminated list of words.
1 NF. Column contains atomic data. Normalize schema to get clean code and better performance.
SQLite
does not have built-in reverse
function, that is why it is a bit ugly:
CREATE TABLE mytable(id INTEGER NOT NULL, words TEXT );
INSERT INTO mytable(id,words) VALUES (1,'apple, banana, orange, peach, strawberry');
INSERT INTO mytable(id,words) VALUES (2,'car, plane, orange');
INSERT INTO mytable(id,words) VALUES (3,'sheep, car, plane, horse, cow');
INSERT INTO mytable(id,words) VALUES (4,'sheep, cherry, plane, horse, cow');
UPDATE mytable
SET words = CASE
WHEN (LENGTH(words) - LENGTH(REPLACE(words, ',', ''))) < 4
THEN 'cherry, ' || words
ELSE SUBSTR('cherry, ' || words, 1,
LENGTH(words) + LENGTH('cherry, ') -
LENGTH(SUBSTR(SUBSTR(
SUBSTR( SUBSTR(words, INSTR(words,',')+1), INSTR(SUBSTR(words, INSTR(words,',')+1), ',')+1),
INSTR(SUBSTR( SUBSTR(words, INSTR(words,',')+1), INSTR(SUBSTR(words, INSTR(words,',')+1), ',')+1), ',') + 1),
INSTR(SUBSTR(
SUBSTR( SUBSTR(words, INSTR(words,',')+1), INSTR(SUBSTR(words, INSTR(words,',')+1), ',')+1),
INSTR(SUBSTR( SUBSTR(words, INSTR(words,',')+1), INSTR(SUBSTR(words, INSTR(words,',')+1), ',')+1), ',') + 1),',')+1)) -1
)
END
WHERE words NOT LIKE '%cherry%';
SELECT * FROM mytable;
To make it more general you need to change cherry
with your value.
Output:
╔════╦══════════════════════════════════════╗
║ id ║ words ║
╠════╬══════════════════════════════════════╣
║ 1 ║ cherry, apple, banana, orange, peach ║
║ 2 ║ cherry, car, plane, orange ║
║ 3 ║ cherry, sheep, car, plane, horse ║
║ 4 ║ sheep, cherry, plane, horse, cow ║
╚════╩══════════════════════════════════════╝
How it works:
UPDATE ... WHERE words NOT LIKE '%cherry%';
do not update rows that have cherry
alreadySET words = CASE WHEN (LENGTH(words) - LENGTH(REPLACE(words, ',', ''))) < 4
if number of delimeters (commas) is lower than 4 just concatenate value to stringSUBSTRING
from 1 to last commaSQL Server
version for comparison:
DECLARE @val VARCHAR(100) = 'cherry';
UPDATE mytable
SET words = CASE
WHEN LEN(words)-LEN(REPLACE(words, ',', '')) < 4 THEN @val + ', ' + words
ELSE LEFT(@val + ', ' + words,
LEN(@val + ', ' + words) - CHARINDEX(',', REVERSE(words)))
END
WHERE words NOT LIKE '%'+ @val +'%';
SELECT * FROM mytable;