我想根据国家/地区列中逗号分隔的国家/地区名称字符串更新一系列列Country1
,Country2
... Country 9
。我已经这样做了以下的声明:
cur.execute("\
UPDATE t \
SET Country1 = returnCommaDelimitedValue(Country,0),\
Country2 = returnCommaDelimitedValue(Country,1),\
...
Country10 = returnCommaDelimitedValue(Country,9),\
WHERE Country IS NOT NULL\
;")
我的tabe中还有一个名为Genre
的列。现在,我想在同一个语句中更新列Genre1
,Genre2
... Genre9
。我认为这个说法看起来像是:
cur.execute("\
UPDATE t \
SET Country1 = returnCommaDelimitedValue(Country,0), Genre1 = returnCommaDelimitedValue(Genre,0)\
Country2 = returnCommaDelimitedValue(Country,1), Genre2 = returnCommaDelimitedValue(Genre,1)\
...
Country10 = returnCommaDelimitedValue(Country,9), Genre10 = returnCommaDelimitedValue(Genre,9)\
WHERE Country IS NOT NULL\
AND Genre IS NOT NULL
;")
声明是否正确?
答案 0 :(得分:0)
您应该运行2个单独的update
个查询。问题是Country
可以独立于Genre
而为空。因此,无论您在查询的Country IS NOT NULL
子句中合并条件Genre IS NOT NULL
和where
,您都会遗漏一些可能已更新的列,或者您将使用{{1更新某些列值。
现在,我还没有看到null
的实施。当字符串参数为returnCommaDelimitedValue
时,它可能会返回null
。在这种情况下,您可以考虑完全删除null
子句并更新同一查询中的where
和countryN
列。在这种情况下,如果genreN
为Country
,这也会使null
为空,因此这可能是您想要的。如果几乎所有行都有非Country1
null
和Country
,则此方法可能会更快。
答案 1 :(得分:0)
Country1,Country2,Country3 ......这是anti-pattern。你会感觉到非常糟糕的桌子设计的后果。不要觉得太吵,这是一种很常见的反模式。在标准SQL中使用列表很困难且非常不直观。整个混乱被称为“正常化”。
列表由join tables中的one-to-many relationship表示。一个t
有许多国家/地区。这是一个非常重要的话题,但这是一个草图。
而不是将Country1,Country2,Country3等......放在t
中,我将称之为Thing,你将有一个名为ThingCountries的表来表示列表。
create table ThingCountries (
ThingID integer references Thing(id),
Country text
);
属于物品的每个国家都会与物品的ID一起插入到ThingCountries。
# Do this in a loop
insert into ThingCountries (ThingID, Country) values (?, ?)
通过链接Thing.ID和ThingCountries.ThingID来检索它们。
select ThingCountries.Country from Thing
join ThingCountries on Thing.ID = ThingCountries.ThingID
where Thing.ID = ?
通过查询ThingCountries,您可以快速找到哪些东西有某个国家。
select ThingID from ThingCountries
where Country = ?
可以通过简单删除删除它们。
delete from ThingCountries where ThingID = ? and Country = ?
无需知道有多少Country列。没有任何空白可以填补。对于有多少国家来说,没有任何限制。
稍后您可能希望存储有关每个国家/地区的信息,例如其名称和缩写。在这种情况下,您可以创建一个国家/地区表。
create table Country (
id integer primary key,
name text not null,
abbrev text not null
);
然后ThingCountries引用Country by是id而不是存储国家名称。
create table ThingCountries (
ThingID integer references Thing(id),
CountryID integer references Country(id)
);
现在,您可以存储有关每个国家/地区的任何信息,并且可以防止打字错误(因为国家/地区必须存在于“国家/地区”表格中)。
为流派做同样的事情,你的问题就消失了。
这有点尴尬,但SQL就是这样做的。最好习惯它。或者,一些数据库提供数组类型以使其更简单,例如Postgres arrays。
更多阅读: