2012-03-01 48 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