2010-02-11 15 views
16

Hej moje pierwsze pytanie na SO! Anywho ...SQL - Łączenie wielu podobnych zapytań

Wciąż względnie newb w SQL, więc myślę, że być może brakuje czegoś tutaj. Moje pytanie brzmi: mam obecnie stół pełen numerów telefonów. Chcę mieć zapytanie, w którym znajdę numery telefonów podobne do listy, którą mam. Na przykład chcę znaleźć numery telefonów rozpoczynające się od "555123", "555321" i "555987". Wiem, że normalnie, jeśli masz listę numerów, które możesz po prostu zrobić zapytanie, takie jak

SELECT * 
    FROM phonenumbers 
WHERE number in ('5551234567', '5559876543', ....); 

Czy istnieje sposób, aby to zrobić z jak? Takich jak

SELECT * 
    FROM phonenumbers 
WHERE number in like ('555123%', '555321%', '555987%'); //I know this doesn't actually work 

Zamiast to zrobić indywidualnie

SELECT * 
    FROM phonenumbers 
WHERE number like '555123%' 
    or number like '555321%' 
    or number like '555987%'; //Which does work but takes a long time 

Albo jest tam łatwiej to zrobić, że jestem po prostu brakuje? Używam PostgreSQL, nie wiem, czy są jakieś polecenia, które by mu w tym pomogły. Dzięki!

+1

Witamy SO! Mam retagged twoje pytanie, aby wyjaśnić, że odnosi się do postgres – AdaTheDev

+0

Jaką wersję Postgres? Brzmi jak zadanie dla regexes: http://www.postgresql.org/docs/8.3/static/functions-matching.html –

+0

'Które działa, ale zajmuje dużo czasu" - chyba że zmienisz charakter zapytania, inna składniowa reprezentacja tego samego będzie trwała tak długo. Czy kolumna jest indeksowana? – MattH

Odpowiedz

25

można użyć SIMILAR TO i rozdzielić tagi z | Rura '555123%|555321%|555987%'

np

SELECT * 
FROM phonenumbers 
WHERE number SIMILAR TO '555123%|555321%|555987%' 
+1

To było prawie to, czego szukałem, dzięki! Działa dla tego, czego potrzebuję. –

1

Może jeśli prefiksy są tej samej długości, to możesz zrobić where RIGHT(number) in ('123456', '234456', 'etc', 'etc')

2

Nie sądzę więc, ale można dołączyć phonenumbers na stole criteria zawierające wartości, które chcesz pasować, czyli

JOIN criteria ON phonenumbers.number LIKE criteria.phonenumbers 

... chyba nie warto dla niewielkiej liczby warunków, choć

+0

mam o wiele więcej do przeszukania, ale pomyślałem, że powinienem zachować to proste za pomocą kilku liczb. –

3

Zakładając wszystkie swoje numery nie zawierają litery:

SELECT number 
FROM (
     VALUES 
     ('555123'), 
     ('555321'), 
     ('555000') 
     ) prefixes (prefix) 
JOIN phonenumbers 
ON  number >= prefix 
     AND number < prefix || 'a' 

ten użyje indeksu na phonenumbers, jeśli w ogóle.

+0

Widziałem bardzo dobre zapytania od twojego użytkownika, skąd się tego nauczyłeś? Czy istnieje książka, która obejmuje wszystkie te rzeczy? – Pentium10

+0

@ Pentium10: Zarabiałem na życie przez 12 lat. Nigdy nie widziałem dobrej książki na temat wewnętrznych baz danych (jeszcze), prawie wszystko to sobie wymyśliłem. – Quassnoi

+0

Czy masz bloga lub intencje, aby napisać książkę na ten temat? Byłbym wśród kupujących. – Pentium10

0

Można również polegać na wyrażeń regularnych POSIX, patrz sekcja 9.7.3 z official documentation.

Na przykład:

SELECT * FROM foobar WHERE name ~ '12345|34567'; 

Ważne jest, aby pamiętać, że pole name jest typu ciąg.

13

późno do partii, ale dla pomyślności ... Można również użyć ANY(array expression)

SELECT * 
FROM phonenumbers 
WHERE number LIKE ANY(ARRAY['555123%', '555321%', '555987%'])