2010-02-11 18 views
16

¡Hola mi primera pregunta sobre SO! Anywho ...SQL - Combinando varias consultas similares

Todavía relativamente nuevo en SQL, así que creo que me puede faltar algo aquí. Mi pregunta es que actualmente tengo una mesa llena de números de teléfono. Quiero hacer una consulta en la que busco números de teléfono similares a los de una lista que tengo. Entonces, por ejemplo, quiero encontrar números de teléfono que comiencen con '555123', '555321' y '555987'. Sé que normalmente si usted tiene una lista de números que sólo podría hacer una consulta como

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

¿Hay una manera de hacer esto con su semejante? Tal como

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

En lugar de tener que hacer esto de forma individual

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

O hay una manera más fácil de hacer esto que estoy solo falta? Estoy usando postgres, no sé si hay algún comando que pueda ayudar con eso. ¡Gracias!

+1

Bienvenido al SO! He retomado su pregunta para aclarar que se relaciona con postgres – AdaTheDev

+0

¿Qué versión de Postgres? Suena como un trabajo para expresiones regulares: http://www.postgresql.org/docs/8.3/static/functions-matching.html –

+0

'Lo cual funciona pero tarda mucho tiempo - a menos que cambie la naturaleza de la consulta, una la representación sintáctica diferente de la misma cosa tomará tanto tiempo. ¿Está indexada la columna? – MattH

Respuesta

25

puede utilizar SIMILAR TO y separar las etiquetas con | tubería '555123%|555321%|555987%'

por ejemplo:

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

Esto era más o menos lo que estaba buscando, ¡gracias! Funciona para lo que necesito –

1

Tal vez si sus prefijos son de la misma longitud, puede hacerlo where RIGHT(number) in ('123456', '234456', 'etc', 'etc')

2

Yo no lo creo, pero podría unirse a phonenumbers en una mesa criteria que contiene los valores que desee para que coincida con el, es decir

JOIN criteria ON phonenumbers.number LIKE criteria.phonenumbers 

... probablemente no vale la pena para un pequeño número de condiciones, aunque

+0

En realidad, tengo mucho más para buscar pero pensé que debería mantenerlo simple con solo unos pocos números. –

3

Suponiendo que todos sus números no contienen letras:

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

para ello se utiliza un índice en phonenumbers, en su caso.

+0

He visto muy buenas consultas de su usuario, ¿dónde aprendió el material? ¿Hay algún libro que cubra todos estos? – Pentium10

+0

@ Pentium10: me he ganado la vida por '12' años. Nunca he visto un buen libro sobre las partes internas de la base de datos (todavía), casi todo esto me he figurado a mí mismo. – Quassnoi

+0

¿Tienes un blog o intenciones de escribir un libro sobre esto? Yo estaría entre los compradores. – Pentium10

0

También puede confiar en las expresiones regulares POSIX, consulte la sección 9.7.3 del official documentation.

Por ejemplo:

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

Es importante tener en cuenta que su campo name es de un tipo de cadena.

13

tarde a la fiesta, pero para la prosperidad ... se puede también utilizar un ANY(array expression)

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