2012-03-01 49 views
0

SQL连接从来没有我的实力。我希望得到这个帮助。对于你的SQL maestros来说,这可能是一件容易的事情。如何使这个Android SQLite加入查询

我有2个表具有相同的列。比方说,他们的结构是:

id INTEGER PRIMARY KEY AUTOINCREMENT, 
key INTEGER, 
description TEXT NOT NULL, 
size INTEGER, 
timestamp LONG, 
is_on INTEGER 

表名是Shirts1Shirts2。这些表格表示数据集的2个版本,并且数据量重叠较多。目标是找出哪些行是不同的。 密钥是从版本到版本保持不变的关键。剩余列可以从版本1更改为2.

答案应该是Android上的SQLite的理想选择。多个查询都可以 - 不需要1个查询。

我的猜测

SELECT * FROM Shirts1, Shirts2 WHERE Shirts1.key=Shirts2.key AND 
     (Shirts1.description != Shirts2.description OR 
     (Shirts1.size != Shirts2.size OR 
     (Shirts1.timestamp != Shirts2.timestamp OR 
     (Shirts1.is_on != Shirts2.is_on) 

另一个值得关注的是希望Android手机与有限的设备内存上这个事业问题的查询?两个表中都有1000行。我是否应该将查询分解为多个查询,例如将比较次数限制为100行,因为密钥的顺序为1-1000。

+0

它应该工作正常,但尝试在实际数据和检查在实际设备上的性能。 – 2012-03-01 06:42:10

回答

0

Shirt1:

1;1;"green_shirt";1;1;1 
4;4;"yellow_shirt";1;1;1 

Shirt2:

1;1;"green_shirt";1;1;1 
2;2;"red_shirt";1;1;1 
3;3;"orange_shirt";1;1;1 



SELECT shirt2.* 
    FROM shirt1 
    RIGHT OUTER JOIN shirt2 ON shirt1.key = shirt2.key 
WHERE shirt1.description != shirt2.description OR 
     IFNULL(shirt1.size, -1) != IFNULL(shirt2.size, -1) OR 
     IFNULL(shirt1.timestamp, -1) != IFNULL(shirt2.timestamp, -1) OR 
     IFNULL(shirt1.is_on, -1) != IFNULL(shirt2.is_on, -1)  
UNION ALL 
SELECT shirt1.* 
    FROM shirt2 
RIGHT JOIN shirt1 ON shirt1.key = shirt2.key 
WHERE shirt1.description != shirt2.description OR 
     IFNULL(shirt1.size, -1) != IFNULL(shirt2.size, -1) OR 
     IFNULL(shirt1.timestamp, -1) != IFNULL(shirt2.timestamp, -1) OR 
     IFNULL(shirt1.is_on, -1) != IFNULL(shirt2.is_on, -1) 
UNION ALL 
SELECT shirt1.* 
    FROM shirt1 
INNER JOIN shirt2 ON shirt1.key = shirt2.key 
WHERE shirt1.description = shirt2.description OR 
     IFNULL(shirt1.size, -1) = IFNULL(shirt2.size, -1) OR 
     IFNULL(shirt1.timestamp, -1) = IFNULL(shirt2.timestamp, -1) OR 
     IFNULL(shirt1.is_on, -1) = IFNULL(shirt2.is_on, -1) 

输出:

2;2;"red_shirt";1;1;1 
3;3;"orange_shirt";1;1;1 
4;4;"yellow_shirt";1;1;1 
1;1;"green_shirt";1;1;1 

如果要排除包括在shirt1衬衫/ shirt2你只需要删除最后的联盟。这意味着

SELECT shirt2.* 
    FROM shirt1 
    RIGHT OUTER JOIN shirt2 ON shirt1.key = shirt2.key 
WHERE shirt1.description != shirt2.description OR 
     IFNULL(shirt1.size, -1) != IFNULL(shirt2.size, -1) OR 
     IFNULL(shirt1.timestamp, -1) != IFNULL(shirt2.timestamp, -1) OR 
     IFNULL(shirt1.is_on, -1) != IFNULL(shirt2.is_on, -1)  
UNION ALL 
SELECT shirt1.* 
    FROM shirt2 
RIGHT JOIN shirt1 ON shirt1.key = shirt2.key 
WHERE shirt1.description != shirt2.description OR 
     IFNULL(shirt1.size, -1) != IFNULL(shirt2.size, -1) OR 
     IFNULL(shirt1.timestamp, -1) != IFNULL(shirt2.timestamp, -1) OR 
     IFNULL(shirt1.is_on, -1) != IFNULL(shirt2.is_on, -1) 

输出:

2;2;"red_shirt";1;1;1 
3;3;"orange_shirt";1;1;1 
4;4;"yellow_shirt";1;1;1 

想想你将要在同一列的一切,所以我想这应该是更好的解决方案。如果您对shirt1/shirt2有不同的栏目,那么您还可以使用select *并忽略联合。

关于设备问题:取决于设备,但如果设备是旧的,那么我不认为查询将是您的主要问题。您也可以尝试添加一些索引来提高性能。

编辑:改变了解决方案的加入对键列

+0

我猜整数可以为空这就是为什么ifnull检查是需要..顺便说一句,我相信_key_是我们需要加入。你也可以解释一下“同一列中的所有内容”是什么意思吗? – amit 2012-03-01 20:11:30

+0

我的意思是,如果你选择*,你会得到类似shirt1.key,shirt2.key等等(所以你会得到每一个衬衫的每一列的列)。我认为你会更喜欢一个解决方案,你只有一列(所以对于你将得到一个名为key的单个列与shirt1和two的连接值),并且在这一列中都有两个值。 – Eggi 2012-03-01 20:39:11

+0

我明白了。顺便说一句,你可以做字符串比较**!= **?还是有功能?比较需要是utf8,因为描述可以是外语。 – amit 2012-03-02 00:07:51