0% encontró este documento útil (0 votos)
46 vistas14 páginas

SQL Cc42a

Este documento presenta una introducción al estándar SQL-92. Explica cómo definir esquemas, dominios, tablas, columnas y restricciones. También cubre tipos de datos, claves primarias, claves externas y su comportamiento ante eliminaciones. Finalmente, menciona consultas simples y manipulación de datos.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOC, PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
46 vistas14 páginas

SQL Cc42a

Este documento presenta una introducción al estándar SQL-92. Explica cómo definir esquemas, dominios, tablas, columnas y restricciones. También cubre tipos de datos, claves primarias, claves externas y su comportamiento ante eliminaciones. Finalmente, menciona consultas simples y manipulación de datos.
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como DOC, PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 14

CC42A: Bases de datos

Auxiliar: SQL-92

Profesores: Claudio Gutiérrez, Gonzalo Navarro


Prof. Auxiliar: Rodrigo Paredes

Parte 1. SQL
El efecto producido por los conceptos de modelo relacional los lenguajes relacionales
(álgebra y cálculo) introducidos por E. Codd provocó tal impacto que significó que
comunidades comerciales y de investigación desarrollaran implementaciones de los
lenguajes relacionales. Tal vez el mayor esfuerzo se lo llevó SQL (Structured Query
Languaje), que junto con permitir consultas en la base de datos, contiene primitivas de
definición de tablas, actualización de la base de datos, definición de vistas otorgamientos de
privilegios, etc. A continuación se mostrarán aspectos del estándar ANSI de 1992, conocido
como SQL-92.

Aún cuando las distintos administradores de bases de datos (MySQL, posgreSQL,


ORACLE, etc.) siguen la definición ANSI SQL-92, es necesario verificar con el manual del
administración de la base de datos específica definiciones particulares tales como el tipo de
los datos predefinidos, las funciones, etc.

Definición de tablas y esquemas


Definición de Esquemas

La definición de un esquema es simple. Sólo se necesita identificar el comienzo de la


definición con una instrucción CREATE SCHEMA y una cláusula adicional
AUTHORIZATION y a continuación definir cada dominio, tabla, vista y demás en el
esquema, por ejemplo:

CREATE SCHEMA EMPRESA_CL


  AUTHORIZATION DUEÑO
    definición de dominios
    definición de tablas
    definición de vistas
    etc.

El dueño del esquema, o propietario del esquema puede otorgar privilegios de acceso y
actualización de la base de datos definida en el esquema a otros usuarios del sistema.

Tipos de datos y dominios


Un dominio es un conjunto del cual toma sus valores una columna de una relación. Según
este concepto, los tipos de datos predefinidos son dominios. Adicionalmente SQL-92
permite la definición de dominios por parte de los usuarios.

Numéricos exactos:
 

Integer enteros
Small Integer enteros pequeños
p: precisión: total de números o dígitos en el número
Numeric(p, e)
e: escala: cuantos números están a la derecha del punto decimal
p: precisión
Decimal(p,e)
e: escala

Numéricos aproximados:
 

Real
Double precision doble precisión
float flotante

Estos tipos de datos se utilizan normalmente para cálculos científicos y de ingeniería.

Cadenas de caracteres:
 

Character(n) carácter
Character varying(n) carácter variable

Los campos de character siempre almacenan n caracteres, aún cuando tengan que rellenar
con blancos a la derecha para completar la longitud n. Los campos character varying sólo
almacenan el número real de caracteres que se introdujeron (hasta un máximo de n).

Cadenas de bits:
 

Bit(n)
Bit varying(n)

Estos campos se usan para banderas u otras máscaras de bits para el control.
Fechas y horas:
 

Date fecha
Time hora
Timestamp sello de tiempo
Time con tiempo zonal
Timestamp con tiempo zonal

El tipo Date se da en el orden año, mes, día con cuatro dígitos para el año. El Time se da en
horas (0 a 23), minutos, segundos y décimas de segundos. El Timestamp es la fecha más la
hora.

Intervalos:
 

Year-month año-mes
Day-time día-hora

Un intervalo es la diferencia entre dos fechas (año-mes) o entre dos horas (día-hora).

Definición de dominios:

Los tipos de datos con restricciones (constrains) y valores por defecto (default values) se
pueden combinar en la definición de dominios. Una definición de dominio es un tipo de
datos especializado que puede estar definido dentro de un esquema y utilizado en la
definición de columnas. Por ejemplo:

CREATE DOMAIN IDENTIFICADOR NUMERIC(4) DEFAULT 0


  CHECK (VALUE IS NOT NULL)

Esta definición dice que un dominio llamado IDENTIFICADOR tiene las siguientes
propiedades:

1. Su tipo de datos es numérico de cuatro dígitos.


2. Su valor por defecto es 0.
3. Nunca puede ser nulo.

Definición de Tablas

Las tablas se definen en tres pasos:

1. Dar el nombre de la tabla.


2. Definir cada columna, posiblemente incluyendo restricciones de columna.
3. Definir las restricciones de la tabla.

Siguiendo el ejemplo de EMPRESA_CL y del dominio IDENTIFICADOR:

CREATE SCHEMA EMPRESA_CL


  AUTHORIZATION DUEÑO

CREATE DOMAIN IDENTIFICADOR NUMERIC(4) DEFAULT 0


  CHECK (VALUE IS NOT NULL)

CREATE TABLE TRABAJADOR (


  TRA_ID         IDENTIFICADOR    PRIMARY KEY,
  TRA_NOMBRE     CHARACTER(12),
  TRA_TARIFA_HR  NUMERIC(5,2),
  TRA_OFICIO     CHARACTER(8),
  TRA_SUP        NUMERIC(4),
  FOREIGN KEY ID_SUPV REFERENCES TRABAJADOR
                 ON DELETE SET NULL
)

CREATE TABLE ASIGNACION (


  ASG_ID_TRABAJADOR    IDENTIFICADOR,
  ASG_ID_EDIFICIO      IDENTIFICADOR,
  ASG_FECHA_INICIO     DATE,
  ASG_NUM_DIAS         INTERVAL DAY (3),
  PRIMARY KEY (ASG_ID_TRABAJADOR, ASG_ID_EDIFICIO),
  FOREIGN KEY ASG_ID_TRABAJADOR REFERENCES TRABAJADOR
                       ON DELETE CASCADE,
  FOREIGN KEY ASG_ID_EDIFICIO REFERENCES EDIFICIO
                       ON DELETE CASCADE
)

CREATE TABLE EDIFICIO (


  EDI_ID             IDENTIFICADOR    PRIMARY KEY,
  EDI_DIRECCION      CHARACTER(12),
  EDI_TIPO           CHARACTER(9) DEFAULT 'Oficina'
                     CHECK (TIPO IN ('Oficina', 'Almacén', 'Comercio',
'Residencia')),
  EDI_NIVEL_CALIDAD  NUMERIC(1),
  EDI_CALIDAD        NUMERIC(1) DEFAULT 1
                     CHECK (CATEGORIA > 0 AND CATEGORIA < 4)
)

Después del CREATE SCHEMA y de la definición de dominios (CREATE DOMAIN) van


las instrucciones de creación de tablas. La instrucción CREATE TABLE identifica el
nombre de la tabla, que debe ser única dentro del esquema. Después del CREATE TABLE
van encerradas entre paréntesis y separadas por coma las instrucciones de definición de
columnas y restricciones sobre la tabla.

Las definiciones de columnas de la tabla (que son los atributos del modelo relacional) están
compuestas por:

NombreColumna    TipoDeDatos    [ValorPorDefecto]    [RestriccionesEspecíficas]

El [ValorPorDefecto] y las [RestriccionesEspecíficas] pueden no especificarse, por


ejemplo:

  EDI_DIRECCION      CHARACTER(12),

especificar solamente restricciones específicas:

  EDI_ID             IDENTIFICADOR    PRIMARY KEY,

especificar solamente el valor por defecto:

  EDI_TIPO           CHARACTER(9) DEFAULT 'Oficina',

o especificar valor por defecto y restricciones:

  EDI_CALIDAD        NUMERIC(1) DEFAULT 1


                     CHECK (CATEGORIA > 0 AND CATEGORIA < 4)

Las restricciones de la tabla son por ejemplo:

  FOREIGN KEY ID_SUPV REFERENCES TRABAJADOR


                 ON DELETE SET NULL

  PRIMARY KEY (ASG_ID_TRABAJADOR, ASG_ID_EDIFICIO),


  FOREIGN KEY ASG_ID_TRABAJADOR REFERENCES TRABAJADOR
                       ON DELETE CASCADE,
  FOREIGN KEY ASG_ID_EDIFICIO REFERENCES EDIFICIO
                       ON DELETE CASCADE
 

Analicemos la definición de las llaves:

  PRIMARY KEY (ASG_ID_TRABAJADOR, ASG_ID_EDIFICIO),


significa que ASG_ID_TRABAJADOR y ASG_IS_EDIFICIO son las llaves de la tabla,
por lo tanto los valores combinados de estas dos columnas deben ser únicos para la tabla.
Por otro lado dado que son FOREIGN KEY sabemos que son llaves externas.
  FOREIGN KEY ASG_ID_TRABAJADOR REFERENCES TRABAJADOR
                       ON DELETE CASCADE,
es una clave externa recursiva (referencia a otra fila de su propia relación).

  FOREIGN KEY ASG_ID_EDIFICIO REFERENCES EDIFICIO


                       ON DELETE CASCADE
Es una clave externa normal (referencia a otra relación).

Las palabras ON DELETE indican que hacer en caso de borrar al referido. La cláusula ON
DELETE SET NULL le dice al sistema que si se borra la tupla a la que apunta la clave
externa entonces el valor de ésta se debe poner a cero, esto sirve para mantener la
integridad de referencias (si borro al referido, y quedan referencias apuntando a una tupla
borrada tenemos una falla en la integridad de referencia). La cláusula ON DELETE
CASCADE significa que si se borra la tupla referida en la relación, se realiza un borrado en
"cascada" de todas las tuplas que hacían referencia a ésta.

Similar a ON DELETE tenemos a ON UPDATE  y ambas cláusulas tienen las opciones


siguientes:

 CASCADE
 SET NULL
 SET DEFAULT

Por último se debe decir que a diferencia de las relaciones en el modelo relaciona, no se
requiere que cada tabla SQL tenga una clave primaria. En otras palabras, si no se indica
ninguna clave, entonces dos filas de la tabla pueden tener valores idénticos. Lo malo es que
una tabla que no tenga clave primaria no puede ser referida mediante clave externa desde
otra tabla.

Adicionalmente SQL-92 define instrucciones para cambiar las definiciones de las tablas
(ALTER TABLE) o para borrar las tablas (DROP TABLE). Para borrar un esquema
completo se usa DROP SCHEMA, pero como borrar un esquema es una cosa seria, se tiene
que especificar que opción de borrado se usa:

 DROP SCHEMA NombreEsquema CASCADE: significa eliminar el esquema con


ese nombre al igual que todas las tablas, datos y otros esquemas que aún existan.
 DROP SCHEMA NombreEsquema RESTRICT: significa eliminar el esquema sólo
si todos los restantes objetos del esquema ya han sido borrados.

Manipulación de datos
Consultas simples

Consultas simples: Una consulta que involucra una sola tabla de la base de datos. Ejemplo:
¿Quiénes son los fontanero?
SELECT TRA_NOMBRE
  FROM TRABAJADOR
 WHERE TRA_OFICIO = 'Fontanero'

Acá se muestran las tres cláusulas más usadas en SQL: la cláusula SELECT, la cláusula
FROM y la cláusula WHERE. Una buena regla es escribir cada cláusula en una línea aparte
y con sangrías, aunque se puede escribir todo en la misma línea.

Cláusula SELECT: Señala las columnas que se desean en la consulta (equivalente a la


proyección del álgebra relacional).

Cláusula FROM: Lista las tablas que son referidas por la consulta.

Clausula WHERE: Nos da la condición para seleccionar las filas de las tablas indicadas.

La sentencia SQL anterior se procesa por el sistema en el orden FROM, WHERE,


SELECT.

Otro ejemplo: ¿Cuál es la tarifa semanal de cada electricista?, además entregue la salida
ordenada alfabéticamente.

SELECT TRA_NOMBRE, 'Tarifa semanal = ', 48 * TRA_TARIFA_HR


FROM TRABAJADOR
WHERE TIPO = 'ELECTRICISTA'
ORDER BY TRA_NOMBRE

Noten la inclusion de la cadena de caracteres 'Tarifa semanal = ' al cálculo de la consulta.


Además noten que con la cláusula ORDER BY podemos ordenar la salida, si quisieramos
order descendente, utilizamos "DESC".

Consulta: ¿Quiénes tienen una tarifa por hora entre $7000 y $9000, entregue toda la
información de la tabla?

SELECT *
FROM TRABAJADOR
WHERE TRA_TARIFA_HR >= 7000 AND TRA_TARIFA_HR <= 9000

Se pueden usar los siguientes operadores de comparación: =, <> (distinto), <, >, <=, >=.
Se pueden usar los siguientes conectores booleanos: AND, OR, NOT.

Consulta: Indique los fontaneros, albañiles y electricistas.

SELECT *
FROM TRABAJADOR
WHERE TRA_OFICIO IN ('Fontaneros', 'Albañiles', 'Electricistas')
Consulta: Encontrar todos los trabajadores cuyos oficios comiencen con "Elec". Para esto
necesitamos usar caracteres comodines. es decir, símboles especiales que valen por
cualquier cadena de caracteres.

SELECT *
FROM TRABAJADOR
WHERE TRA_OFICIO LIKE 'Elec%'

SQL tiene dos caracteres comodines, el % que vale por cero o cualquier cantidad de
caracteres, y _ que vale por exactamente un caracter cualquiera. El operador LIKE se usa
para comparar variables de caracteres literales cuando se utilizan comodines.

Consulta: Encuentre todas las asignaciones que comiencen en las dos próximas semanas.

SELECT *
FROM ASIGNACION
WHERE ASG_FECHA_INICIO BETWEEN CURRENT_DATE AND CURRENT_DATE + INTERVAL
'14' DAY

Acá se introduce el operador BETWEEN, que devuelve VERDADERO si el valor está


dentro del intervalo [CURRENT_DAY, CURRENT_DATE + INTERVAL '14' DAY] y
FALSO si no. CURRENT_DAY (fecha actual) es una función que siempre devuelve la
fecha de hoy.
 

Consultas multi-tablas

Consulta: ¿Cuáles son los oficios de los trabajadores asignados al edificio 435?

SELECT TRA_OFICIO
FROM TRABAJADORES, ASIGNACION
WHERE TRA_ID = ASG_ID_TRABAJADOR
  AND ASG_ID_EDIFICIO = 435

En este caso, la cláusula FROM calcula el producto cartesiano de las tablas indicadas y
luego con la cláusula WHERE filtramos las filas interesantes (aquellas en que TRA_ID es
igual a ASG_ID_TRABAJADOR) y luego las que nos interesan (las asignaciones al
edificio 435), y por último SELECT toma la columna que nos interesa. Ojo que cuando hay
problemas de que se repite un nombre de columna le ponemos como prefijo el nombre de la
tabla seguida por un punto, ejemplo: TRABAJADORES.TRA_ID, o
ASIGNACION.ASG_ID_EDIFICIO.

Consulta: Indicar los trabajadores con los nombres de sus supervisores

SELECT A.TRA_NOMBRE, B.TRA_NOMBRE


FROM TRABAJADORES A, TRABAJADORES B
WHERE A.TRA_SUP = B.TRA_ID
En este caso, para resolver la consulta necesitamos dos copias de la tabla, para ello usamos
alias (un nombre alternativo que se le da a una relación) de las tablas A y B para referirnos
a cada copia.
 

Subconsultas
Subconsulta: Una consulta dentro de una consulta.

Consulta: ¿Cuáles son los oficios de los trabajadores asignados al edificio 435?

SELECT TRA_OFICIO
FROM TRABAJADOR
WHERE TRA_ID IN (
  SELECT ASG_ID_TRABAJADOR
  FROM ASIGNACION
  WHERE ASG_ID_EDIFICIO = 435
)

En el ejemplo la subconsulta es:


(
  SELECT ASG_ID_TRABAJADOR
  FROM ASIGNACION
  WHERE ASG_ID_EDIFICIO = 435
)

A veces es posible realizar una sola consulta, sin subconsulta, pero más compleja:

SELECT OFICIO
FROM TRABAJADORES, ASIGNACIONES
WHERE ASG_ID_EDIFICIO = 435
  AND TRA_ID = ASG_ID_TRABAJADOR
 

EXISTS y NOT EXISTS


Operador EXISTS: Evalúa verdadero si el conjunto resultante es no vacío.
Operador NOT EXISTS: Evalúa verdadero si el conjunto resultante es vacío.

Consulta: ¿Quienes son los trabajadores que no están asignados al edificio 435?

SELECT TRA_ID, TRA_NOMBRE


FROM TRABAJADOR
WHERE NO EXISTS (
  SELECT *
  FROM ASIGNACION
  WHERE ASG_ID_TRABAJADOR = TRA_ID
    AND ASG_ID_EDIFICIO = 435
)

Los operadores EXISTS y NOT EXISTS siempre preceden a una subconsulta.

Además esta subconsulta tiene apellido, es una subconsulta correlacionada, es decir, es una
subconsulta cuyos resultados dependen de la fila que se está examinando por una consulta
más externa.

Funciones integradas
Consulta: ¿Cuáles son la tarifa por hora mayor y menor?

SELECT MAX(TRA_TARIFA_HR), MIN(TRA_TARIFA_HR)


FROM TRABAJADOR

Consulta: ¿Cuál es el promedio de días que los trabajadores están asignados al edificio 435?

SELECT AVG(ASG_NUM_DIAS)
FROM ASIGNACION
WHERE ASG_ID_EDIFICIO = 435

Consulta: ¿Cuál es el número total de días asignados a fontanería en el edificio 312?

SELECT SUM(ASG_NUM_DIAS)
FROM ASIGNACION, TRABAJADOR
WHERE TRA_ID = ASG_ID_TRABAJADOR
  AND TRA_OFICIO = 'Fontanero'
  AND ASG_ID_EDIFICIO = 312

Consulta: ¿Cuántos tipos de oficios diferentes hay?

SELECT COUNT(DISTINC TRA_OFICIO)


FROM TRABAJADOR

La palabra clave DISTINCT se usa para que el sistema no cuente el mismo tipo de oficio
mas de una vez.

Como muestran todos estos ejemplos, si una función integrada aparece en una cláusula
SELECT, entonces nada más que funciones integradas pueden aparecer en dicha cláusula
SELECT. La una excepción ocurre en combinación con la cláusula GROUP BY.

GROUP BY y HAVING
Cláusula GROUP BY: Indica cuáles filas deben agruparse sobre un valor común de las
columna(s) especificada(s)
Cláusula HAVING: Una cláusula que impone condiciones a los grupos.

A diferencia de ORDER BY que se ejecutan sólo para ordenar la salida, GROUP BY y


HAVING permiten generar particiones (grupos de datos) para realizar operaciones sobre
las particiones.

Consulta: Para cada supervisor, ¿Cuál es la tarifa por horas más alta que se le paga a un
trabajador que informe a este supervisor?

SELECT TRA_SUP, MAX(TRA_TARIFA_HR)


FROM TRABAJADOR
GROUP BY TRA_SUP

Consulta: Para cada supervisor que dirige a más de un trabajador, ¿cuál es la tarifa por
horas más alta que se le paga a un trabajador que informe a dicho supervisor?

SELECT TRA_SUP, MAX(TRA_TARIFA_HR)


FROM TRABAJADOR
GROUP BY TRA_SUP
HAVING COUNT(*) > 1

Noten que la cláusula WHERE aplica a las filas, en cambio la cláusula HAVING a
grupos !!, aunque pueden trabajar juntos WHERE y HAVING.

Consulta: Para cada supervisor que dirige a más de un trabajador, ¿cuál es la tarifa por
horas más alta que se le paga a un electricista que informe a dicho supervisor?

SELECT TRA_SUP, MAX(TRA_TARIFA_HR)


FROM TRABAJADOR
WHERE TRA_OFICIO = 'Electricista'
GROUP BY TRA_SUP
HAVING COUNT(*) > 1
 

Operaciones de modificación de la base de datos


NSERT: Operación que causa que se añadan filas a una relación.
UPDATE: Operación que cambia los valores de las columnas en las filas.
DELETE: Operación que quita filas de una relación.

Inserción:
INSERT INTO ASIGNACION (ASG_ID_TRABAJADOR, ASG_ID_EDIFICIO,
ASG_FECHA_INICIO)
VALUES (1284, 485, '2002-05-13')

Actualización:

UPDATE TRABAJADOR
SET TRA_TARIFA_HR = 1.05 * TRA_TARIFA_HR
WHERE ID_SUPV = 1520

Borrado:

DELETE FROM TRABAJADOR


WHERE ID_SUPV 1520
 

Definición de vistas
Una vista es una porción restringida de la base de datos, y se obtiene de una tabla que
contiene información básica o real. Por ejemplo si quisieramos crear una vista de la tabla
TRABAJADOR pero que no muestre su tarifa por hora:

CREATE VIEW TRABAJADOR_B


AS SELECT TRA_ID, TRA_NOMBRE., TRA_OFICIO, TRA_SUP
  FROM TRABAJADOR

En general para definir una vista se utiliza:

CREATE VIEW NombreVista


AS ConsultaSQL

Parte 2. Más ejemplos


Considere el siguiente esquema:
CLIENTE{CLI_ID, CLI_NOMB, CLI_RENTA_ANUAL}
EMBARQUE{EMB_ID, EMB_ID_CLI, EMB_PESO, EMB_ID_CAMION, EMB_DESTINO}
Clave Foránea: EMB_CLI_ID referencia a CLI_ID en CLIENTE
Clave Foránea: EMB_DESTINO referencia a CIU_NOMBRE en CIUDAD
Clave Foránea: EMB_ID_CAMION referencia a CAM_ID en CAMION
CAMION{CAM_ID, CAM_NOMBRE_CHOFER}
CIUDAD{CIU_NOMBRE, CIU_POBLACION}
¿Cómo se llaman los clientes que han enviado paquetes a Sioux City?

SELECT CLI_NOMBRE
FROM CLIENTE, EMBARQUE
WHERE CLI_ID = EMB_ID_CLI
  AND EMB_DESTINO = 'Sioux'

¿Quiénes son los choferes que han conducido embarques de clientes que tienen renta anual
sobre los $20 millones a ciudades con población por encima del millón?

SELECT CAM_NOMBRE_CHOFER
FROM CLIENTE, EMBARQUE, CAMION, CIUDAD
WHERE CLI_RENTA_ANUAL > 20000000
  CIU_POBLACION > 1000000
  AND CLI_ID = EMB_ID_CLI
  AND CAM_ID = EMB_ID_CAMION
  AND CIU_NOMBRE = EMB_DESTINO

Indique el nombre y la renta anual de los clientes que han enviado embarques que pesan
más de 100 libras

SELECT CLI_NOMBRE, CLI_RENTA_ANUAL


FROM CLIENTE
WHERE CLI_ID IN (
  SELECT EMB_ID_CLI
  FROM EMBARQUE
  WHERE EMB_PESO > 100
)

Indique los choferes que han transportado embarques a cada una de las ciudades.
Esto es equivalente a determinar cuáles son los choferes tales que NO hay una ciudad a la
cual NO hayan llevado un embarque.

SELECT C1.CAM_NOMBRE_CHOFER
FROM CAMION C1
WHERE NOT EXISTS (
  SELECT CIU_NOMBRE
  FROM CIUDADES
  WHERE NOT EXISTS (
    SELECT *
    FROM EMBARQUE, CAMION C2
    WHERE EMB_DESTINO = CIU_NOMBRE
      AND EMB_ID_CAMION = CAM_ID
      AND C2.CAM_NOMBRE_CHOFER = C1.CAM_NOMBRE_CHOFER
  )
)
De una lista de los clientes que hacen todos sus envíos a una sola ciudad. (Note que la
ciudad no tiene que ser la misma para cada cliente)

SELECT CLI_NOMB
FROM CLIENTE
WHERE 1 IN (
    SELECT COUNT(DISTINC EMB_DESTINO)
    FROM EMBARQUE
    WHERE EMB_ID_CLIENTE = CLI_ID
  )

Para cada ciudad que haya recibido al menos diez paquetes, ¿cuál es el peso medio de los
paquetes enviado a dicha ciudad?

SELECT EMB_DESTINO, AVG(EMB_PESO)


FROM EMBARQUE
GROUP BY EMB_DESTINO
HAVING COUNT(*) > 10
 

También podría gustarte