SQLite:删除或替换某些列,不要用NULL覆盖其他列?

dnph8jn4  于 2023-11-21  发布在  SQLite
关注(0)|答案(4)|浏览(122)

假设我有一个表(冰箱),列:(日期(pk),水果,蔬菜,淀粉,糖果)。下面是一个示例行:

date     | fruits | veggies | starches | sweets 
20180220 | melon  | potato  |  pasta   | fudge

字符串
我想在冰箱中插入或替换某些列,如下所示:

> INSERT or REPLACE into refrigerator (date, fruits, veggies, starches) VALUES ("20180220", "apple", "carrot", "bread")


当我这样做时,如果我没有为(sweets)指定一个值,它会被NULL覆盖。

date     | fruits | veggies | starches | sweets 
20180220 | apple  | carrot  |  bread   | NULL


什么是正确的方法来做到这一点,不取代我指定的值?
我相信这是很明显的事情。尽管嘲笑我吧。

y53ybaqx

y53ybaqx1#

现在它可以正常工作了,如果行不存在,它也会删除它。没有UNION ALL,它就不能正常工作。第一个SELECT使用COALESCE()来在行存在的情况下保留现有的列值。第二个SELECT使用NOT EXISTS来覆盖行不存在的情况,所以它构造了一个。因此,UNION ALL只返回1行:从现有行中删除“合并”行,或者新建一行。然后,REPLACEINTO通过主键将合并/创建的行替换回表中。

CREATE TABLE refrigerator
  (
  date TEXT(8) NOT NULL PRIMARY KEY
  , fruits TEXT(50) NULL
  , veggies TEXT(50) NULL
  , starches TEXT(50) NULL
  , sweets TEXT(50) NULL
  );

INSERT INTO refrigerator (date, fruits, veggies, starches, sweets)
VALUES ("20180220", "melon", "potato", "pasta", "fudge");

REPLACE INTO refrigerator (date, fruits, veggies, starches, sweets)
SELECT
  date
  , COALESCE("apple", fruits) as fruits
  , COALESCE("carrot", veggies) as veggies
  , COALESCE("bread", starches) as starches
  , COALESCE(NULL, sweets) as sweets
 FROM
   refrigerator
 WHERE
   date = "20180220"
UNION ALL
SELECT
  T.date, T.fruits, T.veggies, T.starches, T.sweets
FROM
(
SELECT
  "20180220" as date
  , "apple" as fruits
  , "carrot" as veggies
  , "bread" as starches
  , NULL as sweets
) AS T
WHERE
  NOT EXISTS (SELECT * FROM refrigerator AS R WHERE R.date = T.date);

SELECT date, fruits, veggies, starches, sweets FROM refrigerator;

字符串
这是一个SQL Fiddle:冰箱SQL Fiddle
x1c 0d1x的数据

dgjrabp2

dgjrabp22#

我用两条线解决了这个问题。

UPDATE refrigerator SET fruits='apple', veggies='carrot', starches='bread' WHERE date='20180220';

字符串
然后

INSERT or IGNORE INTO refrigerator (fruits, veggies, starches) VALUES ("apple", "carrot", "bread");


我是倒着想的,这可能会使这里的答案过于复杂。我首先更新特定的列,如果一行(日期)存在。下一行将插入一个新的行,如果它不存在,则忽略它。
有没有任何并发症,可能会出现这种方式做吗?我已经测试过了,它的工作都符合预期到目前为止。

uujelgoq

uujelgoq3#

要更新现有数据,请使用Update
https://www.tutorialspoint.com/sqlite/sqlite_update_query.htm
将fruits列更新为apple使用的示例
更新refigerator set fruits = 'Apple' where YOURBACK ECLAUSEHERE
至于插入什么是期望被插入,如果你不提供任何东西?该程序是不会读你的心。

cgfeq70w

cgfeq70w4#

在提出这个问题的时候,SQLite中还没有这个功能。
我使用UPSERT(https://sqlite.org/lang_upsert.html)解决了这个问题。

INSERT INTO refrigerator (date, fruits, veggies, starches) VALUES ("20180220", "apple", "carrot", "bread")
 ON CONFLICT(date) DO UPDATE SET fruits="apple", veggies="carrot", starches="bread";

字符串
它尝试将数据重新写入数据库,当由于唯一性约束而发生冲突时,它会执行UPDATE;因此,现有数据保持不变,仅更改指定的列。

相关问题