2011-04-18 87 views
4

試圖做同樣的事情this question,但這次在sqlite中。在我目前的應用程序中,我需要能夠做這種類型的查詢:sqlite元組比較

SELECT First, Last, Score 
FROM mytable 
WHERE 
    ('John', 'Jordan', 5) <= (First, Last, Score) 
    AND (First, Last, Score) <= ('Mike', 'Taylor', 50) 
ORDER BY First, Last, Score 
LIMIT 1 

,並得到('Liz', 'Jordan', 2)答案,給出這樣的數據:

+-------+---------+-------+ 
| First | Last | Score | 
+-------+---------+-------+ 
| Liz | Jordan |  2 | 
| John | Jordan |  2 | 
| Liz | Lemon | 10 | 
| Mike | Taylor | 100 | 
| John | Jackson | 1000 | 
| Mike | Wayne |  1 | 
| Liz | Lemon | 20 | 
| Liz | Meyers |  5 | 
| Bruce | Jackson |  1 | 
+-------+---------+-------+ 

什麼是實現最有效的方法這在sqlite中?請記住,這是一個玩具示例,而且我的實際應用程序具有包含更多列和數據類型以及數億行的表。

如果解決方案可以輕鬆擴展到更多/更少的列,那就更好了。


元組比較:

元組字典順序,這意味着序列進行排序與​​它們的第一不同的元件。例如,(1,2,x)<(1,2,y)返回與x < y相同的值。

值得注意的是SQL-92(以及mysql,oracle,postresql)正確地實現了這一點。該標準使用「行值構造函數」來表示我調用的元組。該行爲在part 8.2.7, page 209中極爲詳細地定義。


這裏是必要的SQL創建的例子:

create table mytable (First char(20), Last char(20), Score int); 
insert into mytable values ('Liz', 'Jordan', 2); 
insert into mytable values ('John', 'Jordan', 2); 
insert into mytable values ('Liz', 'Lemon', 10); 
insert into mytable values ('Mike', 'Taylor', 100); 
insert into mytable values ('John', 'Jackson', 1000); 
insert into mytable values ('Mike', 'Wayne', 1); 
insert into mytable values ('Liz', 'Lemon', 20); 
insert into mytable values ('Liz', 'Meyers', 5); 
insert into mytable values ('Bruce', 'Jackson', 1); 
create unique index 'UNIQ' on mytable (First, Last, Score); 

回答

4

SQLite不支持的元組進行比較。但是行構造函數是一種速記。您可以使用更復雜的WHERE子句獲得相同的結果。我省略了LIMIT 1子句,以便更容易地看到兩個查詢返回相同的集合。 (在支持排構造的平臺,那就是。)

這種比較

ROW(a,b) <= ROW(c,d) 

相當於

a < c OR (a = c AND b <= d) 

而且,因爲你需要,你可以擴展爲多列。

SELECT First, Last, Score 
FROM mytable 
WHERE 
     (('John' < First) OR 
     ('John' = First AND 'Jordan' < Last) OR 
     ('John' = First AND 'Jordan' = Last AND 5 <= Score)) 
    AND ((First < 'Mike') OR 
     (First = 'Mike' AND Last < 'Taylor') OR 
     (First = 'Mike' AND Last = 'Taylor' AND Score <= 50)) 
ORDER BY First, Last, Score 

Liz Jordan 2 
Liz Lemon 10 
Liz Lemon 20 
Liz Meyers 5 

我沒有在數據中用NULL來測試這個。

+0

我不知道是否mysql優化器足夠聰明,知道這與元組語法相同。 – bukzor 2011-04-27 05:38:03

+0

@ bukzor:對。我會糾正我的答案。 – 2011-04-27 11:51:20

1

我一直在通過使用字符串連接(||)和字符序列來避免字段不「合併」並導致不正確的匹配(-),以避免元組比較的缺失。

(First, Last, Score) <= ('Mike', 'Taylor', 50) 

成爲

First||' - '||Last||' - '||Score <= 'Mike'||' - '||'Taylor'||' - '||'50' 

First||' - '||Last||' - '||Score <= 'Mike - Taylor - 50' 

所以你SELECT

SELECT First, Last, Score 
FROM mytable 
WHERE 
    'John - Jordan - 5' <= First||' - '||Last||' - '||Score 
    AND First||' - '||Last||' - '||Score <= 'Mike - Taylor - 50' 
ORDER BY First, Last, Score 
LIMIT 1 

字符串連接是非常昂貴和不夠簡潔,但它的工作方式相同,並看起來非常相似。

+0

只有在轉義連接的字符串時,這纔是通用的。你認爲這比@ catcall的答案有更好的表現嗎? – bukzor 2013-01-29 17:06:02