Consultas de Selección: Concatenación y Ordenación¶
Conexión a la Base de Datos¶
[1]:
import pandas as pd
import psycopg2
import sqlalchemy
import matplotlib as plt
%matplotlib inline
from sqlalchemy import create_engine
POSTGRES_ADDRESS = 'localhost' # Este es el servidor, puede ser una IP
POSTGRES_PORT = '5432'
POSTGRES_USERNAME = 'postgres'
POSTGRES_PASSWORD = '1234'
POSTGRES_DBNAME = 'dvdrental'
# Ahora se configura la cadena de conexión.
# Esta es una cadena que contiene los parámetros necesarios para establecer una
# conexión con posgres.
postgres_str = ('postgresql://{username}:{password}@{ipaddress}:{port}/{dbname}'.format(username=POSTGRES_USERNAME,
password=POSTGRES_PASSWORD,
ipaddress=POSTGRES_ADDRESS,
port=POSTGRES_PORT,
dbname=POSTGRES_DBNAME))
# A continuación se crea la conexión
cnx = create_engine(postgres_str)
Concatenación¶
[2]:
#Operador de Concatenación y los Alias
SQL = '''SELECT first_name || ' ' || last_name as nombre_completo, email as correo
FROM customer;'''
datos = pd.read_sql_query(SQL, cnx)
datos
[2]:
nombre_completo | correo | |
---|---|---|
0 | Jared Ely | jared.ely@sakilacustomer.org |
1 | Mary Smith | mary.smith@sakilacustomer.org |
2 | Patricia Johnson | patricia.johnson@sakilacustomer.org |
3 | Linda Williams | linda.williams@sakilacustomer.org |
4 | Barbara Jones | barbara.jones@sakilacustomer.org |
... | ... | ... |
594 | Terrence Gunderson | terrence.gunderson@sakilacustomer.org |
595 | Enrique Forsythe | enrique.forsythe@sakilacustomer.org |
596 | Freddie Duggan | freddie.duggan@sakilacustomer.org |
597 | Wade Delvalle | wade.delvalle@sakilacustomer.org |
598 | Austin Cintron | austin.cintron@sakilacustomer.org |
599 rows × 2 columns
[3]:
# Acceso a un atributo específico
datos.nombre_completo
[3]:
0 Jared Ely
1 Mary Smith
2 Patricia Johnson
3 Linda Williams
4 Barbara Jones
...
594 Terrence Gunderson
595 Enrique Forsythe
596 Freddie Duggan
597 Wade Delvalle
598 Austin Cintron
Name: nombre_completo, Length: 599, dtype: object
[4]:
#Operador de Concatenación y los Alias con espacio en blanco
SQL = '''SELECT first_name || ' ' || last_name as "nombre completo", email correo
FROM customer;'''
datos = pd.read_sql_query(SQL, cnx)
datos
[4]:
nombre completo | correo | |
---|---|---|
0 | Jared Ely | jared.ely@sakilacustomer.org |
1 | Mary Smith | mary.smith@sakilacustomer.org |
2 | Patricia Johnson | patricia.johnson@sakilacustomer.org |
3 | Linda Williams | linda.williams@sakilacustomer.org |
4 | Barbara Jones | barbara.jones@sakilacustomer.org |
... | ... | ... |
594 | Terrence Gunderson | terrence.gunderson@sakilacustomer.org |
595 | Enrique Forsythe | enrique.forsythe@sakilacustomer.org |
596 | Freddie Duggan | freddie.duggan@sakilacustomer.org |
597 | Wade Delvalle | wade.delvalle@sakilacustomer.org |
598 | Austin Cintron | austin.cintron@sakilacustomer.org |
599 rows × 2 columns
[5]:
# Acceso a un atributo específico cuando el alias tiene espacio en blanco
datos['nombre completo']
[5]:
0 Jared Ely
1 Mary Smith
2 Patricia Johnson
3 Linda Williams
4 Barbara Jones
...
594 Terrence Gunderson
595 Enrique Forsythe
596 Freddie Duggan
597 Wade Delvalle
598 Austin Cintron
Name: nombre completo, Length: 599, dtype: object
Ordenación¶
[6]:
# Primer nombre ordenado ascendentemente (a -> z) y apellido ordenado descendentemente (z -> a),
# de todos los clientes con nombre que comienza por K
SQL = '''SELECT first_name, last_name FROM customer
WHERE first_name LIKE 'K%'
ORDER BY first_name ASC, last_name DESC'''
pd.read_sql_query(SQL, cnx)
[6]:
first_name | last_name | |
---|---|---|
0 | Karen | Jackson |
1 | Karl | Seal |
2 | Katherine | Rivera |
3 | Kathleen | Adams |
4 | Kathryn | Coleman |
5 | Kathy | James |
6 | Katie | Elliott |
7 | Kay | Caldwell |
8 | Keith | Rico |
9 | Kelly | Torres |
10 | Kelly | Knott |
11 | Ken | Prewitt |
12 | Kenneth | Gooden |
13 | Kent | Arsenault |
14 | Kevin | Schuler |
15 | Kim | Cruz |
16 | Kimberly | Lee |
17 | Kirk | Stclair |
18 | Kristen | Chavez |
19 | Kristin | Johnston |
20 | Kristina | Chambers |
21 | Kurt | Emmons |
22 | Kyle | Spurlock |
[7]:
# Ordene los nombres por la cantidad de letras que contengan descendentemente
SQL = '''SELECT first_name as primer_nombre, LENGTH(first_name) as conteo_letras
FROM customer
ORDER BY conteo_letras desc;'''
pd.read_sql_query(SQL, cnx)
[7]:
primer_nombre | conteo_letras | |
---|---|---|
0 | Christopher | 11 |
1 | Jacqueline | 10 |
2 | Constance | 9 |
3 | Katherine | 9 |
4 | Nathaniel | 9 |
... | ... | ... |
594 | Ida | 3 |
595 | Sue | 3 |
596 | Sam | 3 |
597 | Dan | 3 |
598 | Jo | 2 |
599 rows × 2 columns
Manejo de Nulos en Order By¶
NULLes un marcador que indica los datos faltantes o los datos son desconocidos en el momento de la inserción. Cuando ordena las filas que contiene NULL, puede especificar el orden de NULL con otros valores no nulos utilizando la opción NULLS FIRST o NULLS LAST de la cláusula ORDER BY.
[10]:
# Eliminar la tabla para el ejemplo en caso de que exista
sql = '''
DROP TABLE IF EXISTS wait_list;
'''
cnx.execute(sql)
[10]:
<sqlalchemy.engine.result.ResultProxy at 0x21d7506d610>
[11]:
# Crearemos una tabla para ejemplificar el manejo de NULOS usando SQLAlchemy
from sqlalchemy import Table, Column, Integer, String, MetaData
meta = MetaData()
lista_espera = Table(
'wait_list', meta,
Column('id', Integer, primary_key = True),
Column('name', String),
Column('lastname', String),
)
meta.create_all(cnx)
[12]:
# Se inserta un registro
ins = lista_espera.insert().values(id = 1923, name = 'Robert', lastname = 'Maldani')
result = cnx.execute(ins)
str(ins)
[12]:
'INSERT INTO wait_list (id, name, lastname) VALUES (:id, :name, :lastname)'
[13]:
# Se inserta un registro
ins = lista_espera.insert().values(id = 3456, name = 'Natalia', lastname = 'Rosas')
result = cnx.execute(ins)
str(ins)
[13]:
'INSERT INTO wait_list (id, name, lastname) VALUES (:id, :name, :lastname)'
[14]:
# Se inserta un registro, nótese que es posible enviar la sentencia construida manualmente
ins = "INSERT INTO wait_list (id, name, lastname) VALUES ('1234', 'Manuela', 'Saenz')"
cnx.execute(ins)
[14]:
<sqlalchemy.engine.result.ResultProxy at 0x21d72c49820>
[15]:
# Se inserta un registro con un atributo faltante
ins = lista_espera.insert().values(id = 5465, name = 'Julieta')
result = cnx.execute(ins)
str(ins)
[15]:
'INSERT INTO wait_list (id, name) VALUES (:id, :name)'
[16]:
#Realizamos la consulta, los nulos primero
SQL = '''SELECT *
FROM wait_list
ORDER BY lastname NULLS FIRST;'''
pd.read_sql_query(SQL, cnx)
[16]:
id | name | lastname | |
---|---|---|---|
0 | 5465 | Julieta | None |
1 | 1923 | Robert | Maldani |
2 | 3456 | Natalia | Rosas |
3 | 1234 | Manuela | Saenz |
[17]:
#Realizamos la consulta, los nulos al final
SQL = '''SELECT *
FROM wait_list
ORDER BY lastname NULLS LAST;'''
pd.read_sql_query(SQL, cnx)
[17]:
id | name | lastname | |
---|---|---|---|
0 | 1923 | Robert | Maldani |
1 | 3456 | Natalia | Rosas |
2 | 1234 | Manuela | Saenz |
3 | 5465 | Julieta | None |
[18]:
# Se elimina la tabla, por finalizar el ejemplo
lista_espera.drop(cnx, checkfirst=True)
# También es posible enviar directamente la sentencia SQL
# sql = 'DROP TABLE IF EXISTS wait_list;'
# result = cnx.execute(sql)