如何使用具有多个条件的单个语句更新多个列

时间:2016-09-25 19:57:27

标签: sqlite

我想根据国家/地区列中逗号分隔的国家/地区名称字符串更新一系列列Country1Country2 ... 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的列。现在,我想在同一个语句中更新列Genre1Genre2 ... 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
                ;")

声明是否正确?

2 个答案:

答案 0 :(得分:0)

您应该运行2个单独的update个查询。问题是Country可以独立于Genre而为空。因此,无论您在查询的Country IS NOT NULL子句中合并条件Genre IS NOT NULLwhere,您都会遗漏一些可能已更新的列,或者您将使用{{1更新某些列值。

现在,我还没有看到null的实施。当字符串参数为returnCommaDelimitedValue时,它可能会返回null。在这种情况下,您可以考虑完全删除null子句并更新同一查询中的wherecountryN列。在这种情况下,如果genreNCountry,这也会使null为空,因此这可能是您想要的。如果几乎所有行都有非Country1 nullCountry,则此方法可能会更快。

答案 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

更多阅读: