如何使用CSV文件更新表中的所有列值?
问题描述:
我希望使用我导入的CSV文件替换名为songs
的sqlite3(Clementine)数据库表中的列值,并将其命名为songsnew
。如何使用CSV文件更新表中的所有列值?
CSV文件有三列,其中的字段名称与目标数据库中的字段名称匹配。我希望它“索引”到的共同列是filename
。
使用SQLiteBrowser,我想这SQL从另一个答案采取:
update songs
set lastplayed = (select songsnew.lastplayed
where songsnew.filename = songs.filename)
where
exists (
select *
from songsnew
where songsnew.filename = songs.filename
)
它没有工作。该错误消息说:
no such column: songsnew.lastplayed: update songs
...这是奇怪的,因为作为我打字是SQL到SQLite数据库浏览器,它可以正确标识为songsnew
表“弹出”列filename
。
使用SQLite3和/或bash,只能通过将CSV作为表格导入来完成此操作吗?哪种方法最简单,它是如何完成的?我不想一次一个地手动更新数千条记录。
的要求,在评论,这里是第一架构songs
:
CREATE TABLE `songs` (
`title` TEXT,
`album` TEXT,
`artist` TEXT,
`albumartist` TEXT,
`composer` TEXT,
`track` INTEGER,
`disc` INTEGER,
`bpm` REAL,
`year` INTEGER,
`genre` TEXT,
`comment` TEXT,
`compilation` INTEGER,
`length` INTEGER,
`bitrate` INTEGER,
`samplerate` INTEGER,
`directory` INTEGER NOT NULL,
`filename` TEXT NOT NULL,
`mtime` INTEGER NOT NULL,
`ctime` INTEGER NOT NULL,
`filesize` INTEGER NOT NULL,
`sampler` INTEGER NOT NULL DEFAULT '0',
`art_automatic` TEXT,
`art_manual` TEXT,
`filetype` INTEGER NOT NULL DEFAULT '0',
`playcount` INTEGER NOT NULL DEFAULT '0',
`lastplayed` INTEGER,
`rating` INTEGER,
`forced_compilation_on` INTEGER NOT NULL DEFAULT '0',
`forced_compilation_off` INTEGER NOT NULL DEFAULT '0',
`effective_compilation` TEXT NOT NULL DEFAULT '0',
`skipcount` INTEGER NOT NULL DEFAULT '0',
`score` INTEGER NOT NULL DEFAULT '0',
`beginning` INTEGER NOT NULL DEFAULT '0',
`cue_path` TEXT,
`unavailable` INTEGER DEFAULT '0',
`effective_albumartist` TEXT,
`etag` TEXT,
`performer` TEXT,
`grouping` TEXT
);
...这里是为CSV架构导入后文件songsnew:
CREATE TABLE `songsnew` (
`filename` TEXT,
`playcount` TEXT,
`lastplayed` TEXT
);
答
这里是一个更方便的方法:
with delta(fn, pc, lp) as
(select a.filename, a.playcount, a.lastplayed from songsnew a)
update songs set
lastplayed = ifnull((select lp from delta where fn = filename), lastplayed),
playcount = ifnull((select pc from delta where fn = filename), playcount)
where filename in (select fn from delta);
它使用
- 的CTE为各地歧义获得,
with delta(fn, pc, lp) as ...
- 一个结构来填充的值,你可能无法在songsnew有,
ifnull(...)
- 一个WHERE子句加快,
(中ifnull构造也可以防止其他地方发生变化,但速度要慢得多)
您可能想要通过songsnew.playc增加songs.playcount在这种情况下,使用 playcount = ifnull((select playcount+pc from delta where fn = filename), playcount)
。
在SQLite 3.18.0 2017-03-28
你是如何获得数据到SQLiteBrowser的?如果你已经导入它,它已经在那里。在'sqlite3'命令行shell中显示'.schema'的输出。 –
好的 - 上面已经添加了。 – user3447273
列在那里。你把它导入到同一个数据库吗? –