SQLite,根据列中较高的值合并两个表

时间:2013-02-24 03:19:41

标签: android sqlite

我有两个SQLite数据库,每个数据库都有一个表,我需要通过合并具有相同键的行来保持同步。表格如下:

CREATE TABLE titles ( name    TEXT    PRIMARY KEY,
                      chapter TEXT               ,
                      page    INTEGER DEFAULT 1  ,
                      updated INTEGER DEFAULT 0  );

我希望能够在两个表中的每个表上运行相同的命令,结果是对于具有相同名称的行对,在中具有更大值的行中更新将完全覆盖另一行,并且复制没有匹配的行,因此两个表在完成时都是相同的。

这适用于Android应用,因此我可以在Java中进行比较,但如果可能的话,我更喜欢SQLite解决方案。我对SQL不是很熟悉,所以你能给出的解释越多,它就越有帮助。

修改
澄清:我需要一些我可以在任意时间执行的东西,由其他代码调用。两个数据库中的一个并不总是存在,并且当另一个数据库的操作发生时可能不完整,因此我认为触发器不起作用。

2 个答案:

答案 0 :(得分:0)

为此,您可以使用触发器。

CREATE TRIGGER sync_trigger 
AFTER INSERT OR UPDATE OF updated ON titles
REFERENCING NEW AS n
FOR EACH ROW
DECLARE updated_match;
DECLARE prime_name;
DECLARE max_updated;
BEGIN
    SET prime_name = n.name;
    ATTACH database2name AS db2;
    SELECT updated
    INTO updated_match
    FROM db2.titles t
    WHERE t.name=prime_name)

    IF updated_match is not null THEN
        IF n.updated > updated_match THEN
            SET max_updated=n.updated;
        ELSE
            SET max_updated=updated_match;
        END IF;

        UPDATE titles
        SET updated=max_updated
        WHERE name=prime_name;

        UPDATE db2.titles
        SET updated=max_updated
        WHERE name=prime_name;
    END IF;
END sync_trigger;

语法可能有些偏差。我不经常使用触发器,这是一个相当复杂的触发器,但它应该让你知道至少从哪里开始。您需要将其分配给一个数据库,将“database2name”交换为另一个数据库的名称,然后再将其分配给另一个数据库,将“database2name”交换为另一个数据库。

希望这有帮助。

答案 1 :(得分:0)

假设您的主数据库中有另一个数据库attached

ATTACH '/some/where/.../the/other/db-file' AS other;

您可以先删除所有要覆盖的记录,因为他们的updated字段小于另一个表中相应的updated字段:

DELETE FROM main.titles
WHERE updated < (SELECT updated
                 FROM other.titles
                 WHERE other.titles.name = main.titles.name);

然后复制所有较新和缺失的记录:

INSERT INTO main.titles
SELECT * FROM other.titles
WHERE name NOT IN (SELECT name
                   FROM main.titles);

要以另一个方向更新,请交换main / other数据库名称。