Introducción
El SQL es un lenguaje
interactivo y de programación estándar para obtener información
de una base de datos y actualizar ésta. Aunque el SQL es un
estándar tanto ANSI como ISO, muchos productos de bases de
datos soportan el SQL con extensiones propias del lenguaje
estándar.
Las solicitudes asume
|
Tabla_direcciones_empleados
|
| DNI |
Apellidos |
Nombre |
Dirección |
Ciudad |
Provincia |
| 23987739 |
García |
Antonio |
C/ Mayor 2 |
Valencia |
Valencia |
| 45623890 |
López |
Juan |
Pl. Ayuntamiento |
Alicante |
Alicante |
|
En la forma de un
lenguaje de comandos que nos permite seleccionar, insertar,
actualizar, descubrir la ubicación de datos y demás. Existe
también una interfaz de programación.
Bases de la sentencia SELECT
En una BD relacional, los datos
son almacenados en tablas. Un ejemplo de tabla puede contener
el DNI, el nombre y la Dirección:
Ahora, vamos a ver que habría que
hacer para ver las direcciones de todos los empleados. Utiliza
la sentencia SELECT de la siguiente manera:
SELECT Nombre,
Apellidos, Dirección, Ciudad, Provincia
FROM Tabla_direcciones_empleados;
Los siguiente es el resultado de
tu consulta de la BD:
Nombre Apellidos
Dirección
Ciudad Provincia
------------------------------------------------------------
Antonio García
C/ Mayor2
Valencia Valencia
Juan
López
Pl. Ayuntamiento Alicante Alicante
La explicación de lo que acabas de hacer es la siguiente,
has preguntado por todos los datos de la Tabla_direcciones_empleados,
y específicamente, has preguntado por la columnas llamadas
Nombre, Apellidos, Dirección, Ciudad y Provincia. Date cuenta
que los nombre de las columnas y los nombres de las tablas
no tienen espacios...éstos deben ser escritos con una palabra;
y que la sentencia acaba con un punto y coma (;). La forma
general para una sentencia SELECT, recuperando las filas
de una tabla es:
SELECT NombreColumna,
NombreColumna, ...
FROM NombreTabla;
Para coger todas las columnas de
una tabla sin escribir todos los nombres de columna, usa:
SELECT * FROM NombreTabla;
Cada administrador de BD's (DBMS,
"Data Management System") y tipo de software de BD's tienen
diferentes métodos para identificarse en la base de datos
e introducir comandos SQL.
Selección Condicional
Para un mayor estudio de la sentencia SELECT, echa un vistazo
a una nueva tabla de ejemplo:
|
Tabla_estadistica_empleados
|
| Cod_empleado |
Salario |
Beneficios |
Cargo |
| 101 |
75000 |
15000 |
Encargado |
| 105 |
65000 |
15000 |
Encargado |
| 152 |
60000 |
15000 |
Encargado |
| 215 |
60000 |
12500 |
Encargado |
| 244 |
50000 |
12000 |
Técnico |
| 300 |
45000 |
10000 |
Técnico |
| 335 |
40000 |
10000 |
Técnico |
| 400 |
32000 |
7500 |
Aprendiz |
| 441 |
28000 |
7500 |
Aprendiz |
|
Operadores
Relacionales
Hay seis operadores relacionales en SQL, y después de introducirlos,
veremos como usarlos:
| = |
Igual |
| < ó != |
No igual (ver manual para más información) |
| < |
Menor que |
| |
Mayor que |
| <= |
Menor o igual a |
| = |
Mayor o igual que |
|
La cláusula WHERE es usada para especificar que
sólo ciertas filas de la tabla sean mostradas, basándose en
el criterio descrito en esta cláusula WHERE. Es más fácil de
entender viendo un par de ejemplos:
Si quieres ver el Cod_empleado
de aquellos que tengan un salario por encima de 50.000, usa
la siguiente expresión:
SELECT Cod_empleado
FROM Tabla_estadistica_empleados
WHERE Salario = 50000;
Observa que el signo = (mayor o
igual que) ha sido usado, ya que queremos ver listados juntos
aquellos que ganen más de 50.000 o igual a 50.000 . Esto muestra:
Cod_empleado
---------------
010
105
152
215
244
La descripción WHERE Salario =
50.000, es conocida como condición. Lo mismo puede ser utilizado
para la columnas de tipo texto:
SELECT Cod_empleado
FROM Tabla_estadistica_empleados
WHERE Cargo = 'Encargado';
Esto muestra la código de todos
los encargados. Generalmente, con las columnas de texto, usa
igual o no igual a, y comprueba que el texto que aparece en
la condición está dentro de comillas simples.
Más Condiciones
Complejas: Condiciones Compuestas
El operador AND junta dos o más condiciones, y muestra sólo
las filas que satisfacen TODAS las condiciones listadas. Por
ejemplo:
SELECT Cod_empleado
FROM Tabla_estadistica_empleados
WHERE Salario 40000 AND Cargo = ‘Técnico’
El operador OR junta dos o más
condiciones, y devuelve una fila si ALGUNA de las condiciones
listadas en verdadera. Para ver todos aquellos que ganan menos
de 40.000 o tienen menos de 10.000 en beneficios listados
juntos, usa la siguiente consulta:
SELECT ID_EMPLEADO
FROM TABLA_ESTADISTICA_EMPLEADOS
WHERE SALARIO < 40000 OR BENEFICIOS < 10000;
AND & OR pueden ser combinadas, por ejemplo:
SELECT ID_EMPLEADO
FROM TABLA_ESTADISTICA_EMPLEADOS
WHERE CARGO = 'Encargado' AND SALARIO 60000 OR
BENEFICIOS 12000;
Primero, SQL encuentra las filas
donde el salario es mayor de 60.000 y la columna del cargo
es igual a Encargado, una vez tomada esta nueva lista de filas,
SQL buscará si hay otras filas que satisfagan la condición
AND previa o la condición que la columna de los Beneficios
sea mayor de 12.000. Consecuentemente, SQL solo muestra esta
segunda nueva lista de filas, recordando que nadie con beneficios
sobre 12.000 será excluido ya que el operador OR incluye una
fila si el resultado de alguna de las partes es VERDADERO.
Date cuenta que la operación AND se ha hecho primero.
Para generalizar este proceso,
SQL realiza las operaciones AND para determinar las filas
donde las operaciones AND se mantienen VERDADERO (recordar:
todas las condiciones son verdaderas), entonces estos resultados
son usados para comparar con las condiciones OR, y solo muestra
aquellas filas donde las condiciones unidas por el operador
OR se mantienen ciertas para alguna de las partes de la condición..
Para realizar OR antes de AND,
p.e., si quisieras ver una lista de empleados ganando un gran
salario (50.000) o con un gran beneficio (10.000), y sólo
quieres que lo mire para los empleados con el cargo de Encargado,
usa paréntesis:
SELECT ID_EMPLEADO
FROM TABLA_ESTADISTICA_EMPLEADOS
WHERE CARGO = 'Encargado' AND (SALARIO 50000 OR
BENEFICIO 10000);
IN & BETWEEN
Un método fácil de usar condiciones compuestas es usando IN
o BETWEEN. Por ejemplo si tu quieres listar todos los encargados
y Técnico:
SELECT ID_EMPLEADO
FROM TABLA_ESTADISTICA_EMPLEADOS
WHERE CARGO IN ('Encargado', 'Técnico');
O para listar aquellos que
ganen más o 30.000, pero menos o igual que 50.000, usa:
SELECT ID_EMPLEADO
FROM TABLA_ESTADISTICA_EMPLEADOS
WHERE SALARIO BETWEEN 30000 AND 50000;
Para listar todos los que
no están en este rango, intenta:
SELECT ID_EMPLEADO
FROM TABLA_ESTADISTICA_EMPLEADOS
WHERE SALARIO NOT BETWEEN 30000 AND 50000;
De forma similar, NOT IN lista todas las filas excluyendo
aquellas de la lista IN.
Usando LIKE
Observa la Tabla_estadistica_empleados,
y di que quieres ver todas las personas en las cuales su apellido
comience por "l":, intenta:
SELECT ID_EMPLEADO
WHERE APELLIDOS LIKE 'L%';
FROM TABLA_ESTADISTICA_EMPLEADOS
El tanto por ciento (%) es
usado para representar un posible carácter (sirve como comodín),
ya sea número, letra o puntuación, o para seleccionar todos
los caracteres que puedan aparecer después de "L". Para encontrar
las personas con el apellidos terminado en "L", usa ‘%L’,
o si quieres la ‘L’ en medio de la palabra ‘%L%’.
El ‘%’ puede ser usado en lugar de cualquier carácter
en la misma posición relativa a los caracteres dados. NOT
LIKE muestra filas que no cumplen la descripción dada. Otras
posibilidades de uso de LIKE, o cualquiera de las condiciones
anteriores son posibles, aunque depende de qué DBMS estés
usando; lo más usual es consultar el manual, o tu administrador
de sistema sobre la posibilidades del sistema, o sólo para
estar seguro de que lo que estás intentando hacer es posible
y correcto. Éste tipo de peculiaridades serán discutidas más
adelante. Esta sección sólo pretende dar una idea de las posibilidades
de consultas que pueden ser escritas en SQL.
CAPÍTULO 2. Uniones
Uniones
En esta sección, sólo estudiaremos las uniones de unión, y
intersección, que en general son las más usadas.
Un buen diseño de una BD sugiere
que cada lista de tabla de datos sea considerada como una
simple entidad, y que la información detallada puede ser obtenida,
en una BD relacional, usando tablas adicionales y uniones.
Primero considera los siguientes
ejemplos de tablas:
|
Propietarios_Antigüedades
|
| ID_Propietario |
ApellidoPropietario |
NombrePropietario |
| 01 |
Jones |
Bill |
| 02 |
Smith |
Bob |
| 15 |
Lawson |
Patricia |
| 21 |
Akins |
Jane |
| 50 |
Fowler |
Sam |
|
|
Pedidos
|
| ID_Propietario |
ProductoPedido |
| 02 |
Table |
| 02 |
Armario |
| 21 |
Silla |
| 15 |
Espejo |
|
|
Antigüedades
|
| ID_vendedor |
ID_comprador |
Producto |
| 01 |
50 |
Cama |
| 02 |
15 |
Table |
| 15 |
02 |
Silla |
| 21 |
50 |
Espejo |
| 50 |
01 |
Armario |
| 01 |
21 |
Cabinet |
| 02 |
21 |
Cofee Table |
| 15 |
50 |
Cahair |
| 01 |
15 |
Jewelry Box |
| 02 |
21 |
Pottery |
| 21 |
02 |
Librería |
| 50 |
01 |
Plant Stand |
|
Claves
Primero, vamos a estudiar el concepto
de claves. Una clave primaria
es una columna o conjunto de columnas que identifican unívocamente
el resto de datos en cualquiera fila. Por ejemplo, en la tabla
Propietarios_Antigüedades, la columna ID_Propietario identifica
unívocamente esa fila. Esto significa dos cosas: dos filas
no pueden tener el mismo ID_Propietario y, aunque dos propietarios
tuvieran el mismo nombre y apellidos, la columna ID_Propietario
verifica que no serán confundidos, porque la columna ID_Propietario
podrá ser usada por el Administrador de la Base de Datos (DBMS)
para diferenciarlos, aunque los nombres sean los mismos.
Una clave ajena
es una columna en una tabla que es clave primaria en otra
tabla, lo que significa que cada dato en una columna con una
clave ajena debe de corresponder con datos, en otra tabla,
cuya columna es clave primaria. En el lenguaje DBMS esta correspondencia
es conocida como integridad referencial. Por
ejemplo, en la tabla Antigüedades, tanto el ID_comprador como
el ID_vendedor son claves ajenas de la clave primaria de la
tabla Propietarios_Antigüedades (ID_Propietario; por supuesto,
se tiene que tener un propietario antiguo antes de poder comprar
o vender cualquier producto), por lo tanto, en ambas tablas,
las columnas ID son usadas para identificar los propietarios
o compradores y vendedores, y por lo tanto ID_Propietario
es la clave primaria de la tabla Propietarios_Antigüedades.
En otras palabras, todos estos datos "ID" son usados para
referirse a los propietarios, compradores, o vendedores de
antigüedades, sin necesidad de usar sus nombres reales.
Creando una Unión
El propósito de estas claves es
el poder referirse a datos de diferentes tablas, sin tener
que repetir los datos en cada una de ellas, este es el poder
de las bases de datos relacionales. Por ejemplo, se pueden
encontrar los nombres de los que han comprado una silla sin
tener que listar el nombre completo de el comprador en la
tabla Antigüedades...puedes conseguir el nombre relacionando
aquellos que compraron una silla con los nombres en la tabla
de Propietarios_Antigüedades usando el ID_Propietario, el
cual relaciona los datos en las dos tablas. Para encontrar
los nombres de aquellos que compraron una silla, usa la siguiente
consulta:
SELECT APELLIDOPROPIETARIO,
NOMBREPROPIETARIO
FROM PROPIETARIOS_ANTIGÜEDADES, ANTIGÜEDADES
WHERE ID_COMPRADOR = ID_PROPIETARIO AND
PRODUCTO = 'Silla';
Date cuenta de lo siguiente sobre
la consulta... las tablas involucradas en la relación son
listadas en la cláusula FROM de la sentencia. En la cláusula
WHERE, primero observa que el PRODUCTO=’Silla’
restringe el listado a aquellos que han comprado una silla.
Segundo, observa como las columnas ID son relacionadas de
una tabla a otra por el uso de la cláusula ID_COMPRADOR=ID_PROPIETARIO.
Sólo cuando los ID coinciden y el objeto comprado es una silla
(por el AND), los nombres de la tabla Propietarios_Antigüedades
serán listados. Debido a que la condición de unión usada es
el signo igual, esta unión se denomina intersección. El resultado
de esta consulta son dos nombres: Smith, Bob & Fowler,
Sam.
Para evitar ambigüedades se puede
poner el nombre de la tabla antes del de la columna, algo
como:
SELECT PROPIETARIOS_ANTIGÜEDADES.APELLIDOPROPIETARIO,
PROPIETARIOS_ANTIGÜEDADES.NOMBREPROPIETARIO
FROM PROPIETARIOS_ANTIGÜEDADES, ANTIGÜEDADES
WHERE ANTIGÜEDADES.ID_COMPRADOR = PROPIETARIOS_ANTIGÜEDADES.ID_PROPIETARIO
AND ANTIGÜEDADES.PRODUCTO = 'Silla';
Sin embargo, como los nombres
de las columnas en cada tabla son diferentes, esto no es necesario.
DISTINCT y Eliminando Duplicados
Consideremos que quieres ver los
ID y los nombres de toda aquellas persona que haya vendido
una antigüedad. Obviamente, quieres una lista donde
cada vendedor sea listado una vez, y no quieres saber cuántos
artículos a vendido una persona, solamente el nombre de las
personas que han vendido alguna antigüedad (para contar, ver
la sección próxima Funciones
Agregadas). Esto significa que necesitaras decir en SQL
que quieres eliminar las filas de vendedores duplicadas, y
sólo listar cada persona una vez. Para hacer esto, uso la
palabra clave DISTINCT.
Primero, necesitaremos una intersección
para la tabla de Propietarios_Antigüedades para conseguir
los datos detallados de las personas, apellidos y nombre.
Sin embargo, recuerda que la columna
ID_vendedor de la tabla Antigüedades es una clave ajena para
la tabla Propietarios_Antigüedades, y por tanto, un vendedor
podría ser listado más de una vez, por cada producto de la
tabla Antigüedades, listando el ID y sus datos, como queremos
eliminar múltiples coincidencias del ID_vendedor en nuestra
lista, usaremos DISTINCT en la columna donde las repeticiones
pueden ocurrir.
Para complicarlo un poco más, además
queremos la lista ordenada alfabéticamente por el Apellido,
después por el Nombre, y por último por su ID_Propietario.
Para ello, usaremos la clausula ORDER BY.
SELECT DISTINCT
ID_VENDEDOR, APELLIDOPROPIETARIO, NOMBREPROPIETARIO
FROM ANTIGÜEDADES, PROPIETARIOS_ANTIGÜEDADES
WHERE ID_VENDEDOR = ID_PROPIETARIO
ORDER BY APELLIDOPROPIETARIO, NOMBREPROPIETARIO,
ID_PROPIETARIO;
En este ejemplo, obtendremos un
listado de todos los propietarios, en orden alfabético por
el Apellido. Para futuras referencias (y si alguien pregunta),
este tipo de uniones son consideradas en la categoría de uniones interiores.
Alias & In/Subconsultas
En esta sección, hablaremos sobre
los Alias, In y el uso de las subconsultas, y como éstas pueden
ser usadas en un ejemplo con tres tablas. Primero, observa
esta consulta que imprime el apellido de aquellos propietarios
que han formulado un pedido y en qué consiste éste, solamente
listando aquellos cuyos pedidos pueden ser atendidos (esto
es, hay un vendedor que posee el producto pedido)
SELECT OWN.APELLIDOPROPIETARIO
Apellido, ORD.PRODUCTOPEDIDO Producto Pedido
FROM PEDIDOS ORD, PROPIETARIOS_ANTIGÜEDADES
OWN
WHERE ORD.ID_PROPIETARIO = OWN.ID_PROPIETARIO
AND ORD.PRODUCTOPEDIDO IN
(SELECT PRODUCTO
FROM ANTIGÜEDADES);
Esto devuelve:
Apellidos Producto Pedido
--------------------------------
Smith Table
Smith Armario
Akins Silla
Lawson Espejo
Hay algunas cosas a tener
en cuenta sobre esta consulta:
- Primero, el "Apellido" y el
"Producto Pedido" en las líneas Select devuelve los títulos
en la salida.
- El OWN & ORD son alias;
éstos son dos nuevos nombres para las dos tablas listadas
en la cláusula FROM que son usado como prefíjos para toda
las notaciones con punto de los nombres de las columnas
en la consulta (ver arriba). Esto elimina ambigüedades,
especialmente en la cláusula de intersección WHERE donde
ambas tablas tienen la columna ID_Propietario, y la notación
con punto dice al SQL que estamos refiriéndonos de dos diferentes
ID_Propietario de dos tablas diferentes.
- Observa que la tabla de Pedidos
está utilizada primero en la cláusula FROM; esto asegura
que el listado hecho basándose en esta tabla, y la tabla
AntiquesOwners, es solamente usado para la información complementaria
(apellidos).
- Más importante, el AND en la
cláusula WHERE fuerza en la subconsulta el ser invocada
("=ANY" or "=SOME", son dos equivalente usos de IN). Qué
significa esto, la subconsulta se realiza, devolviendo todos
los productos que pertenecen a alguien de la tabla de Antigüedades,
como si no hubiera la cláusula WHERE. Así pues, para que
una fila de la tabla de Pedidos sea listada, el ProductoPedido
debe de ser devuelto en la lista de productos con propietario
de la tabla de Antigüedades, ésta lista un producto sólo
si el pedido puede ser cumplido por otro propietario. Puedes
pensar que este es el camino: la subconsulta devuelve un
conjunto de productos los cuales son comparados con los
de la tabla Pedidos; la condición In es verdadera sólo si
el producto deseado está en el conjunto devuelto de la tabla
Antigüedades. Además, date cuenta que este caso, en el que
hay una antigüedad disponible para cada demanda, obviamente
no será siempre el caso. Además, observa que cuando IN,
"=ANY", o "=SOME" es usada, estas palabras claves se refieren
a cualquier posible fila seleccionada, no a columnas seleccionadas...esto
es, no puedes poner múltiples columnas en una.
CAPÍTULO 3.
Misceláneo de Sentencias SQL
Funciones Agregadas
Vamos a ver cinco importantes funciones agregadas: SUM, AVG, MAX , MIN y COUNT. Son llamadas funciones agregadas
porque resumen el resultado de una consulta.
| SUM () |
devuelve el total de todas las fila, satisfaciendo
todas las condiciones de una columna dada, cuando
la columna dada es numérica. |
| AVG () |
devuelve la media de una columna dada. |
| MAX () |
devuelve el mayor valor de una columna dada. |
| MIN () |
devuelve el menor valor en una columna dada. |
| COUNT(*) |
devuelve el número de filas que satisfacen
las condiciones. |
|
Viendo las tablas del principio
del documento, veamos tres ejemplos:
SELECT SUM(SALARIO), AVG(SALARIO)
FROM TABLA_ESTADISTICA_EMPLEADOS;
Esta consulta muestra el
total de todos los salarios de la tabla, y la media salarial
de todas las entradas en la tabla.
SELECT MIN(BENEFICIOS)
FROM TABLA_ESTADISTICA_EMPLEADOS
WHERE CARGO = 'Encargado';
Esta consulta devuelve el menor
valor de la columan de beneficios, de los empleados que son
Managers, la cual es 12.500.
SELECT COUNT(*)
FROM TABLA_ESTADISTICA_EMPLEADOS
WHERE CARGO = 'Técnico';
Esta consulta nos dice cuantos
empleados tienen la categoría de Técnico (3).
Vistas
En SQL, tu puedes (comprueba tu DBA) tener acceso a crear
vistas por ti mismo. Lo que una vista hace es permitirte asignar
resultados de una consulta a una tabla nueva y personal ,
que puedes usar en otras consultas, pudiendo utilizar el nombre
dado a la tabla de tu vista en la cláusula FROM. Cuando accedes
a una vista, la consulta que está definida en la sentencia
que crea tu lista está relacionada (generalmente), y los resultados
de esta consulta son como cualquier otra tabla en la consulta
que escribiste invocando tu vista. Por ejemplo, para crear
una vista:
CREATE VIEW ANTVIEW
AS SELECT PRODUCTOPEDIDO FROM PEDIDOS;
Ahora, escribe una consulta usando
esta vista como tabla, donde la tabla es una listado de todos
los Productos Pedidos de la tabla Pedidos:
SELECT ID_VENDEDOR
FROM ANTIGÜEDADES, ANTVIEW
WHERE PRODUCTOPEDIDO = PRODUCTO;
Esta consulta muestra todos los
ID_vendedor de la tabla de Antigüedades donde el producto,
en esta tabla, aparece en la vista Antview, la cual no es
más que todos los Productos Desired de la tabla Pedidos. El
listado es generado yendo uno por uno por los Productos Antigüos
hasta donde hay una coincidencia con la vista Antview. Las
vistas pueden ser usadas para restringir el acceso a las bases
de datos, así como para simplificar una consulta compleja.
Creando
nuevas tablas
Toda tabla de una base de
datos debe de ser creada alguna vez... veamos como hemos creado
la tabla de Pedidos:
CREATE TABLE
PEDIDOS
(ID_PROPIETARIO INTEGER
NOT NULL,
PRODUCTOPEDIDO CHAR(40)
NOT NULL);
Esta sentencia devuelve el
nombre de la tabla e informa a la DBMS sobre cada columna
en la tabla. Observa que esta sentencia usa tipos de datos
genéricos, y que los tipos de datos pueden ser diferentes
dependiendo del DBMS que estes usando. Algunos tipos de datos
genéricos son:
- Char(x) - Una columna de caracteres,
donde x es el número máximo de caracteres permitido en la
columna.
- Integer – Una columna
de números enteros, positivos o negativos.
- Decimal(x, y) –
Una columna de números decimales, donde x es el número máximo
de digitos del número decimal en la columna e y el número
máximo de dígitos después del punto decimal. Ejemplo: (4,2):
99.99.
- Date - Una columna fecha
tiene un formato especial en cada DBMS.
- Logical – Una columna que sólo
puede tomar dos valores: TRUE o FALSE (verdadero o falso).
Otra nota, NOT NULL significa
que la columna debe tener un valor en cada fila. Si NULL es
usado, la columna podría tener un valor vacio en una de sus
filas.
Modificando Tablas
Vamos a añadir una columna a la
tabla Antigüedades para permitir introducir el precio de un
producto dado:
ALTER TABLE ANTIGÜEDADES
ADD (PRECIO DECIMAL(8,2) NULL);
Los datos para esta nueva columna
pueden ser actualizados o insertados como se muestra a continuación
Añadiendo Datos
Para insertar filas en una tabla, haz lo siguiente:
INSERT INTO ANTIGÜEDADES
VALUES (21, 01, 'Ottoman', 200.00);
Esto inserta los datos en la tabla,
como una nueva fila, columna por columna, en el orden pre-definido.
Veamos como modificar el orden y dejar el Precio en blanco:
INSERT INTO
ANTIGÜEDADES (ID_COMPRADOR, ID_VENDEDOR, PRODUCTO)
VALUES (01, 21, 'Ottoman');
Borrando datos
Vamos a borrar esta nueva
fila de al base de datos:
DELETE FROM
ANTIGÜEDADES
WHERE PRODUCTO = 'Ottoman';
Pero si hay otra fila que
contiene ‘Ottoman’, esta fila también será borrada.
Para diferenciar la fila de otra, lo que haremos será añadir
datos:
DELETE FROM
ANTIGÜEDADES
WHERE PRODUCTO = 'Ottoman' AND ID_COMPRADOR
= 01 AND ID_VENDEDOR = 21;
Actualizando Datos
Vamos a actualizar el Precio en
una fila que todavía no tiene el precio:
UPDATE ANTIGÜEDADES
SET PRECIO = 500.00 WHERE PRODUCTO = 'Silla';
Esto pone el precio de todas las
sillas a 500.00, como en el caso anterior, añadiendo más condicionantes
en la cláusula WHERE, podemos especificar más aquellas filas
que queremos modificar.
CAPÍTULO 4. Misceláneo de
Tópicos
Índices
Los índices permiten a DBMS acceder a los datos más rápidamente
(esto no ocurre en todos los sistemas). El sistema crea esta
estructura de datos interna (el índice) con la cual se es
posible seleccionar filas, cuando la selección se basa en
columnas indexadas, esto se hace más rápidamente. Este índice
le dice a la DBMS donde esta cierta fila dando el valor de
una columna indexada, como un libro, cuyo índice te dice en
que páginas aparece una cierta palabra. Vamos a crear un índice
por el ID_Propietario en la tabla Propietarios_Antigüedades:
CREATE INDEX OID_IDX
ON PROPIETARIOS_ANTIGÜEDADES (ID_PROPIETARIO);
Ahora en los nombres:
CREATE INDEX NAME_IDX
ON PROPIETARIOS_ANTIGÜEDADES (APELLIDOPROPIETARIO, NOMBREPROPIETARIO);
Para borrar un índice, utiliza
la sentencia DROP:
DROP INDEX OID_IDX;
Así mismo, también puedes "borrar"
una tabla (DROP TABLE nombretabla). En el segundo ejemplo,
el índice se mantine en las dos columnas, agregado junto.
Algunos DBMS no fuerzan la existencia
de claves primarias; en otras palabra, la unicidad de una
columna no es forzada automáticamente. Lo que significa que,
por ejemplo, si intento insertar otra fila dentro de la tabla
Propietarios_Antigüedades con el ID_Propietario de 02, algunos
sistemas lo permitirán hacer, incluso, si esta columna es
la única de la tabla (cada fila se supone que es diferente).
Una forma de evitar esto es crear un único índice en la columna
que queramos que sea la clave primaria para forzar al sistema
a prohibir los duplicados.
CREATE UNIQUE INDEX
OID_IDX ON PROPIETARIOS_ANTIGÜEDADES (ID_PROPIETARIO);
GROUP BY & HAVING
Un uso especial de GROUP BY es asociar una función agregada
(especialmente COUNT) con grupos de filas. Primero, imagina
que la tabla Antigüedades tiene la columna Precio, y que cada
fila tiene un valor para esta columna. Queremos ver el precio
del producto más caro comprado por cada comprador. Tenemos
que decirle a SQL que agrupe cada tipo de compra, y nos diga
la compra que tenga el máximo precio:
SELECT ID_COMPRADOR,
MAX(PRECIO)
FROM ANTIGÜEDADES
GROUP BY ID_COMPRADOR;
Ahora, queremos decir que sólo
queremos ver la precio máximo de la compra si éste es sobre
$1000, así que usamos la cláusula HAVING:
SELECT ID_COMPRADOR,
MAX(PRECIO)
FROM ANTIGÜEDADES
GROUP BY ID_COMPRADOR
HAVING PRECIO 1000;
Más subconsultas
Otro uso común de las subconsultas involucra el uso de operadores
para permitir a una condición WHERE incluir la salida de un
Select de una subconsulta. Primero, lista los compradores
que compraron un producto caro (el precio del producto es
$100 mayor que la media de precio de todos los productos):
SELECT ID_COMPRADOR
FROM ANTIGÜEDADES
WHERE PRECIO
(SELECT AVG(PRECIO)
+ 100
FROM ANTIGÜEDADES);
La subconsulta calcula la media
del Precio más $100, y usando esta figura, los ID_Propietario
son impresos por cada producto que cuesta más. Se puede usar
DISTINCT ID_PROPIETARIO, para eliminar duplicados.
Lista los apellidos de aquellos
de la tabla AntiqueOwner, SÓLO si han comprado un producto:
SELECT APELLIDOPROPIETARIO
FROM PROPIETARIOS_ANTIGÜEDADES
WHERE ID_PROPIETARIO IN
(SELECT DISTINCT ID_COMPRADOR
FROM ANTIGÜEDADES);
La subconsulta devuelve la lista
de compradores, y el apellido es impreso para un Antique Owner
si y sólo si el ID_Propietario aparece en la lista de la subconsulta
(también llamada lista de candidatos). Nota: en algunas DBMS,
el igual puede ser usado de la misma forma que IN, aunque,
por previsión, IN es una mejor elección.
Para un ejemplo de actualización,
nosotros sabemos que el hombre que compró la librería tiene
el Nombre equivocado en la base de datos, éste debería ser
John:
UPDATE PROPIETARIOS_ANTIGÜEDADES
SET NOMBREPROPIETARIO = 'John'
WHERE ID_PROPIETARIO =
(SELECT ID_COMPRADOR
FROM ANTIGÜEDADES
WHERE PRODUCTO = 'Librería');
Primero, la subconsulta encuentra
el ID_comprador de la persona(s) que compró la librería, después
la consulta de salida actualiza el apellido.
Recuerda esta regla sobre las subconsultas:
cuando tienes una subconsulta como parte de una condición
WHERE, la cláusula Selec en la subconsulta tiene que tener
columnas que concuerden en número y tipo con aquellas que
formen parte de la condición WHERE de la subconsulta. En otras
palabras, si tienes "WHERE ColumnName = (SELECT...);", Select
debe de tener sólo una columna en ella, para coincidir con
la salida en la cláusula Where, y estas deberán de coincidir
en tipo
EXISTS & ALL
EXISTS usa una subconsulta como condición, donde la condición
es verdadera si la subconsulta devuelve alguna fila, y falsa
si la subconsulta no devuelve ninguna fila; esta es una característica
no intuitiva con sólo algunos usos. Sin embargo, si un empleado
quiere ver la lista de Owners sólo si hay sillas disponibles,
intenta:
SELECT NOMBREPROPIETARIO,
APELLIDOPROPIETARIO
FROM PROPIETARIOS_ANTIGÜEDADES
WHERE EXISTS
(SELECT *
FROM ANTIGÜEDADES
WHERE PRODUCTO = 'Silla');
Si hay alguna silla en la columna
Antigüedades, la subconsulta devolverá una o varias filas,
haciendo la cláusula EXISTS verdadera, haciendo que SQL liste
los Antique Owners. Si no ha habido sillas, ninguna fila será
devuelta por la subconsulta.
ALL es otra construcción poco usual
, como las consultas ALL pueden ser usadas con diferentes
y simples métodos, veamos un ejemplo de consulta:
SELECT ID_COMPRADOR,
PRODUCTO
FROM ANTIGÜEDADES
WHERE PRECIO = ALL
(SELECT PRECIO
FROM ANTIGÜEDADES);
Esto devolverá el precio de producto
más alto (o más de un producto si hay un empate), y su comprador.
La subconsulta devuelve una lista de todos los precios de
la tabla Antigüedades, y la consulta de salida va fila por
fila de la tabla Antigüedades y si el precio es mayor o igual
a todos (o ALL) precios en la lista, es listado, dando el
precio del producto más caro. La razón de "=" es que el mayor
precio en la lista puede ser igual al de la lista, ya que
este producto está en la lista de precios.
UNION & Uniones de salida
Hay ocasiones donde puedes querer
ver los resultados de múltiples consultas a la vez combinando
sus salidas; usa UNION. Por ejemplo,
si queremos ver todos los ID_COMPRADOR de la tabla de Antigüedades
junto con los ID_PROPIETARIO de la tabla de PEDIDOS, usaremos:
SELECT ID_COMPRADOR
FROM ANTIGÜEDADES
UNION
SELECT ID_PROPIETARIO
FROM PEDIDOS;
SQL requiere que la lista de Select
(de columnas) coincida, columna por columna, en el tipo de
datos. En este caso ID_comprador y ID_Propietario son del
mismo tipo (integer). Además, SQL elimina automáticamente
los duplicados cuando se usa UNION (como si ellos fuera dos
"conjuntos"); en las consultas simples, tienes que usar DISTINCT.
La unión de salida es usada cuando
una consulta de unión está "unida" con filas no incluidas
en la unión, y son especialmente útiles si las "flags" son
incluidas. Primero observa la consulta:
SELECT ID_PROPIETARIO,
'is in both Pedidos & Antigüedades'
FROM PEDIDOS, ANTIGÜEDADES
WHERE ID_PROPIETARIO = ID_COMPRADOR
UNION
SELECT ID_COMPRADOR, 'is in Antigüedades
only'
FROM ANTIGÜEDADES
WHERE ID_COMPRADOR NOT IN
(SELECT ID_PROPIETARIO
FROM PEDIDOS);
Esta consulta hace una unión para
listar todos los propietarios que están en ambas tablas, y
pone una línea etiqueta después de ID repitiendo la cita.
La UNION une esta lista con al siguiente lista. La segunda
lista es generada primero listando aquellos ID que no están
en la tabla Pedidos, generando una lista de ID excluidos de
la consulta de unión. Entonces, cada fila en la tabla Antigüedades
es escaneada, y si el ID_comprador no está en esta lista de
exclusión, es listado con su cita etiqueta. Debe haber un
modo más sencillo de hacer esta lista, pero es difícil generar
la informativa cita de texto.
Este concepto es muy útil en situaciones
donde la clave primaria está relacionada con una clave ajena,
pero el valor de la clave ajena para algunas claves primarias
es NULL. Por ejemplo, en una tabla, la clave primaria es vendedor,
y en otra tabla es clientes, con el nombre de los vendedores
en la misma fila. Sin embargo, si un vendedor no tiene clientes,
el nombre de esta persona no aparecerá en la tabla de clientes.
La unión de salida es usada si el listado de todos los vendedores
va ha ser impreso, junto con sus clientes, aunque el vendedor
no esté en la tabla de clientes, pero está en la tabla de
vendedores. En otro caso, el vendedor será listado con cada
cliente.
CAPÍTULO 5. SQL EMBEBIDO
SQL embebido
Un feo ejemplo (no escribas un
programa como este ...esto es sólo con propósitos educativos)
/* - Para verlo,
aquí tienes un programa ejemplo que usa SQL embebido. SQL
embebido permite
a los programadores conectar con una base de datos e incluir
código SQL en su programa, y poder usar,
manipular y procesar datos de la base de datos..
- Este ejemplo de programa en C (usando SQL embebido) imprimirá
un informe.
- Este programa deberá ser precompilado para las sentencias
SQL, antes de la compilación normal.
- Las partes EXEC SQL son las mismas (estándar), pero el código
C restante deberá ser cambiado,
incluyendo la declaración de variables si estás usando un
lenguaje diferente.
-SQL embebido cambia de sistema a sistema, así que, una vez
más, comprueba la documentación, especialmente la declaración
de variables y procedimientos, en donde las consideraciones
del DBMS y el sistema operativo son cruciales.
*/
/* ***************************************************/
/* ESTE PROGRAMA NO ES COMPILABLE O EJECUTABLE */
/* SU PROPOSITO ES SÓLO DE SEVIR DE EJEMPLO
*/
/****************************************************/
#include <stdio.h>
/* Esta sección declara
las variables locales, estas deberán ser las variables que
tu programa use, pero también
las variables SQL podrán ser utilizadas para tomar o dar valores
*/
EXEC SQL BEGIN DECLARE
SECTION;
int ID_comprador;
char Nombre[100], Apellidos[100], Producto[100];
EXEC SQL END DECLARE SECTION;
/* Esto incluye la
variable SQLCA , aquí puede haber algún error si se compilase.
*/
EXEC SQL INCLUDE
SQLCA;
main() {
/* Este es un posible
camino para conectarse con la base de datos */
EXEC SQL CONNECT
UserID/Password;
/* Este código informa
si estás conectado a la base de datos o si ha habido algún
error durante la conexión*/
if(sqlca.sqlcode)
{
printf(Printer, "Error conectando al servidor
de la base de datos.\n");
exit();
}
printf("Conectado al servidor de la base de datos.\n");
/* Esto declara un
"Cursor". Éste es usado cuando una consulta devuelve más de
una fila, y una operación va a ser realizada en cada fila
resultante de la consulta. Con cada fila establecida por esta
consulta, lo usare en el informe. Después "Fetch" será usado
para sacar cada fila, una a una, pero para la consulta que
está actualmente ejecutada, se usará el estamento "Open".
El "Declare" simplemente establece la consulta.*/
EXEC SQL DECLARE
ProductoCursor CURSOR FOR
SELECT PRODUCTO,
ID_COMPRADOR
FROM ANTIGÜEDADES
ORDER BY PRODUCTO;
EXEC SQL OPEN ProductoCursor;
/* +-- Podrías
desear poner un bloque de chequeo de errores aquí. --+ */
/* Fetch pone los
valores de la "siguiente" fila de la consulta en las variables
locales, respectivamente. Sin embargo, un "priming fetch"
(tecnica de programación) debe ser hecha antes. Cuando el
cursor está fuera de los datos, un código SQL debe de ser
generado para permitirnos salir del bucle. Para simplificar,
el bucle será dejado cuando ocurra cualquier código SQL, incluso
si es una código de error. De otra manera, un código de chequeo
específico debería de ser preparado*/
EXEC SQL FETCH ProductoCursor
INTO :Producto, :ID_comprador;
while(!sqlca.sqlcode)
{
/* Con cada fila,
además hacemos un par de cosas. Primero, aumentamos el precio
$5 (honorarios por tramitaciones) y extraemos el nombre del
comprador para ponerlo en el informe. Para hacer esto, usaremos
Update y Select, antes de imprimir la línea en la pantalla.
La actuaclización, sin embargo, asume que un comprador dado
sólo ha comprado uno de todos los productos dados, o sino,
el precio será incrementado demasiadas veces. Por otra parte,
una "FilaID" podría haber sido utilizada (ver documentación).
Además observa los dos puntos antes de los nombres de las
variables locales cuando son usada dentro de sentencias de
SQL.*/
EXEC SQL UPDATE ANTIGÜEDADES
SET PRECIO = PRECIO + 5
WHERE PRODUCTO = :Producto AND ID_COMPRADOR
= :ID_comprador;
EXEC SQL SELECT NOMBREPROPIETARIO, APELLIDOPROPIETARIO
INTO :Nombre, :Apellidos
FROM PROPIETARIOS_ANTIGÜEDADES
WHERE ID_COMPRADOR = :ID_comprador;
printf("%25s %25s %25s", Nombre, Apellidos, Producto);
/* Feo informe- sólo para propositos de ejemplo!. Veamos la
siguiente fila */
EXEC SQL FETCH ProductoCursor INTO :Producto,
:ID_comprador;
}
/* Cierra el cursor, entrega los cambios (ver debajo), y sale
del programa */
EXEC SQL CLOSE ProductoCursor;
EXEC SQL COMMIT RELEASE;
exit();
}
CAPÍTULO 6. Cuestiones
Comunes & Tópicos Avanzados
Por qué no puede preguntar
simplemente por las tres primeras filas de la tabla? Porque
en las bases de datos relacionales, las filas son insertadas
en un orden particular, esto es, el sistema las inserta en
un orden arbitrario; así, que sólo puedes pedir filas usando
un válida construcción SQL, como ORDER BY, etc.
¿Qué es eso de DDL y DML?.
DDL (Data Definition Language) se refiere
a (en SQL) a la sentencia de creación de tabla... DML (Data
Manipulation Language) se refiere a las sentencia Select,
Update, Insert y Delete.
¿No son las tablas de las
bases de datos como ficheros? Bueno, el DBMS
almacena los datos en ficheros declarados por los administrados
del sistema antes de que nuevas tablas son creadas (en grandes
sistemas), pero el sistema almacena los datos en un formato
especial, y puede diseminar los datos de una tabla sobre muchos
archivos. En el mundo de la base de datos, un conjunto de
archivos creados por la base de datos es llamado "tablespace".
En general, en pequeños sistemas, todos lo relacionado con
una base de datos (definiciones y todo los datos de la tabla)
son guardados en un archivo.
¿Són las tablas de datos
como hojas diseminadas? No, por dos razones. Primeras, las hojas diseminadas
pueden tener datos en una celda, pero una celda es más que
una simple intersección de fila-columna. Dependiendo del software
de diseminación de hojas, una celda puede contener formulas
y formatos, los cuales no pueden ser tenidos por una tabla
de una base de datos. Segundo, las celdas diseminadas son
usualmente dependientes de datos en otras celdas. En las bases
de datos, las celdas son independientes, excepto que las columnas
estén lógicamente relacionadas (por suerte, una fila de columnas,
describe, en conjunto, una entidad), y, cada fila en una tabla
es independiente del resto de filas.
¿Cómo puedo importar un archivo
texto de datos dentro de una base de datos?
Bueno, no puedes hacerlo directamente...
debes usar una utilidad, como "Oracle’s SQL*Loader",
o escribir un programa para cargar los datos en la base de
datos. Un programa para hacerlo simplemente iría de registro
en registro de un archivo texto, dividiéndolo en columnas,
y haciendo un Insert dentro de la base de datos.
¿Qué es un esquema?
Un esquema es un conjunto lógico de tablas,
como la base de datos Antigüedades arriba... usualmente, se
piensa en él simplemente como "la base de datos", pero una
base de datos puede contener más de un esquema. Por ejemplo,
un esquema estrella está compuesto de tablas, donde una gran
y central tabla tiene toda la información importante, con
la que se accede, vía claves ajenas, a tablas dimensionales,
las cuales tienen información de detalle, y pueden ser usadas
en una unión para crear informes detallados.
¿Hay algún filtro en general
que puede usar para hacer mis consultas SQL y bases de datos
mejores y más rápidas (optimizadas)? Puedes intentar, si puedes, evitar expresiones
en Selects, tales como SELECT ColumnaA + Columna B, etc. La
consulta optimizada de la base de datos, la porción de la
DBMS que determina el mejor camino para conseguir los datos
deseados fuera de la base de datos, tiene expresiones de tal
forma que puede requerir más tiempo recuperar los datos que
si las columnas fueran seleccionadas de forma normal, y las
expresiones se manejaran programáticamente.
- Si estas usando una unión, trata
de tener las columnas unidas por índices (desde ambas tablas).
- Cuando tengas dudas, índice.
- A no ser que tengas múltiples
cuentas o consultas complejas, usa COUNT(*) (el número de
filas generadas por la consulta) mejor que COUNT(Nombre_Columna).
¿Qué es normalización? Normalización es una técnica de diseño de bases de datos
que sugiere un cierto criterio en la construcción del diseño
de una tabla (decidir que columnas tendrá cada tabla, y creando
la estructura de claves), donde la idea es eliminar la redundancia
de los datos no-claves entre tablas. Normalización se refiere
usualmente a condiciones de forma, y sólo introduciré las tres
primeras, aunque es usual el uso de otras más avanzadas, como
la cuarta, quinta, Boyce-Codd...)
- La Primera Forma Normal
se refiere a mover los datos en diferentes tablas donde
los datos de cada tabla son de tipo similar, dando a cada
tabla una clave primaria.
- Poner los datos en la Segunda Forma Normal
se refiere a remover a otras tablas datos que sólo dependen
de parte de la clave. Por ejemplo, si hubiera dejado los
nombres de antiguos propietarios en la tabla de productos,
esta no estará en la Segunda Forma Normal, porque los datos
serán redundantes; el nombre será repetido para cada producto
del que se sea propietario; teniendo en cuenta que los nombres
están almacenados en su propia tabla. Los nombre en si mismos
no tienen nada que hacer con los productos, sólo las identidades
de los compradores y vendedores.
- La Tercera Forma Normal
involucra deshacerse de todo aquello de las tablas que no
dependa solamente de la clave primaria. Solo incluye información
que es dependiente de la clave, y mueve a otras tablas que
son independientes de la clave primaria, y crea claves primarias
para las nuevas tablas.
Hay alguna redundancia en cada
forma, y si los datos están en la 3FN , también lo estarán en
la 1FN y en la 2FN, y si lo están en la 2FN, también lo estarán
en la 1FN. En términos de diseño de datos, almacenar los datos,
de tal manera, que cualquier columna no-clave primaria esté
en dependencia sólo de la entera clave primaria. Si observas
el ejemplo de base de datos, verás que la única forma de navegar
através de la base de datos es utilizando uniones usando columnas
clave.
Otros dos importantes puntos en
una base de datos es usar buenos, consistentes, lógicos, y
enteros nombres para las tablas y las columnas, y usar nombres
completos en la base de datos también. En el último punto,
mi base de datos es falta de nombres, así que uso códigos
numéricos para la identificación. Es, usualmente, mejor, si
es posible, tener claves que, por si misma, sea expliquen,
por ejemplo, a clave mejor puede ser las primeras cuatro letras
del apellido y la primera inicial del propietario, como JONEB
por Bill Jones (o para evitar redundancias, añadir un número,
JONEB1, JONEB2 ...).
¿Cuál es la diferencia entre una simple consulta de
fila y una múltiple consulta de filas y por qué es importante
conocer la diferencia? Primero, para cubrir lo obvio,
una consulta de una sólo fila es una consulta que sólo devuelve
una fila como resultado, y una consulta de múltiples filas
es una consulta que devuelve más de una fila como resultado.
Si una consulta devuelva una fila o más esto depende enteramente
del diseño (o esquema) de las tablas de la base de datos.
Como escritor de consultas, debes conocer el esquema, estar
seguro de incluir todas las condiciones, y estructurar tu
sentencia SQL apropiadamente, de forma que consigas el resultado
deseado (aunque sea una o múltiples filas). Por ejemplo, si
quieres estar seguro que una consulta de la tabla Propietarios_Antigüedades
devuelve sólo una fila, considera una condición de igualdad
de la columna de la clave primaria, ID_Propietario.
Tres razones vienen inmediatamente a la mente de por qué esto
es importante. Primero, tener múltiples filas cuando tú sólo
esperabas una, o viceversa, puede significar que la consulta
es errónea, que la base de datos está incompleta, o simplemente,
has aprendido algo nuevo sobre tus datos. Segundo, se estás
usando una sentencia Update o Delete, debes de estar seguro
que la sentencia que estás escribiendo va a hacer la operación
en la fila (o filas) que tú quieres... o sino, estarás borrando
o actualizando más filas de las que querías. Tercero, cualquier
consulta escrita en SQL embebido debe necesitar ser construida
para completar el programa lógico requerido. Si su consulta,
por otra parte, devuelve múltiples filas, deberás usar la
sentencia Fetch, y muy probablemente, algún tipo de estructura
de bucle para el procesamiento iterativo de las filas devueltas
por la consulta.
¿Qué hay de las relaciones?
Otra cuestión de diseño...
el término "relaciones" usualmente se refiere a las relaciones
entre claves ajenas y primarias entre tablas. Este concepto
es importante porque cuando las tablas de una base de datos
relacional es diseñada, estas relaciones debe de ser definidas
porque determinan que columnas son o no claves primarias o
claves ajenas. Debes de haber oido algo sobre el Diagrama
de Entidad-Relación, que es una vista gráfica de las tablas
en el esquema de una base de datos, con líneas conectando
columnas relacionadas entre tablas. Mira el diagrama en el
final de esta sección o algunos de los sitios debajo relacionados
con éste tópico, ya que hay diferentes maneras de dibujar
diagramas de E-R. Pero primero, veamos cada tipo de relación
...
- Una relación Uno-a-Uno
significa que tu tienes una columna clave primaria que está
relacionada con una columna clave ajena, y que para cada
valor de la clave primaria, hay un valor de clave ajena.
Por ejemplo, en el primer ejemplo, la EmployeeAddressTable,
nosotros añadimos una columna ID_EMPLEADO. Entonces, la
EmployeeAddressTable está relacionada con la Tabla_estadistica_empleados
(segundo ejemplo de tabla) por medio de este ID_EMPLEADO.
Específicamente, cada empleado en la EmployeeAddressTable
tiene estadísticas (un fila de datos) en la Tabla_estadistica_empleados.
Incluso, piensa que este es un ejemplo efectuado, es una
relación de "1-1". Además, ten en cuenta, el "tiene" en
fuerte... cuando se expresa una relación, es importante
describir la relación con un verbo.
- Las otras dos tipos de relaciones
pueden o no puede usar claves primarias lógicas y claves
ajenas necesariamente... esto es estrictamente una llamada
del sistema. La primera de éstas es la relación
Uno-a-Muchos ("1-M"). Esto significa que para cada
valor de la columna en una tabla, hay uno o más valores
relaciones en otra tabla. Habrá que añadir de forma necesaria
claves en el diseño o, posiblemente, algún tipo de columna
identificador deberá ser usado para establecer la relación.
Un ejemplo podría ser que para todos ID_Propietario en la
tabla Propietarios_Antigüedades, hubierán uno o mas (cero
también pude ser) productos comprados en la tabla Antigüedades
(verbo: comprar).
- Finalmente, la relación de
Muchos-a-Muchos ("M-M") generalmente no involucra
claves, y usualmente involucra columnas identificativas.
La inusual ocurrencia de un "M-M" significa que una columna
en una tabla está relacionada con otra columna en otra tabla,
y para cada valor de uno de estas dos columnas, hay uno
o más valores relacionados en la correspondiente columna
en la otra tabla (y viceversa), o más comúnmente posible,
dos tablas tienen una relación "1-M" para cada una (dos
relaciones, una 1-M para cada camino). Un (malo) ejemplo
o ésta más común situación podría ser si tuvieras una base
de datos que asignara trabajo, donde una tabla tuviera una
fila por cada empleado y trabajo asignado, y otra tabla
tuviera una fila por trabajo por cada uno de los trabajadores
asignados. Aquí, podrías tener múltiples filas por cada
empleado en la primera tabla, o pro cada trabajo asignado,
y múltiples filas por cada trabajo en la segunda tabla,
una por empleado asignado al proyecto. Estas tablas tienen
un M-M: cada empleado en la primera tabla puede tener tantos
trabajos asignados de la segunda tabla como trabajos haya
en ella, y cada trabajo puede tener tanto empleados como
empleados haya en la primera tabla. Esto es la punta del
iceberg en este tópico... mira los links abajo para más
información y mira en diagrama de debajo para un ejemplo
simplificado de un diagrama de E-R.
CAPÍTULO 7. SQL no estándar
INTERSECT y MINUS son como la sentencia UNION, excepto
que INTERSECT produce filas que apareces en ambas consultas,
y MINUS produce filas que resultan de la primera consulta,
pero no de la segunda.
Generación de construcciones de
informe: la cláusula COMPUTE es puesta al final de una consulta
para poner el resultado en una función agregada al final del
listado, como COMPUTE SUM(PRECIO); Otra opción es usar el
break lógico: definir un break para dividir
un resultado de una consulta dentro de grupos basados en una
columna, como BREAK ON ID_COMPRADOR. Entonces, para
producir un resultado después de listar un grupo, usa COMPUTE
SUM OF PRECIO ON ID_COMPRADOR. Si, por ejemplo, usas las tres
cláusulas juntas (BREAK primero, COMPUTE después del BREAK,
y COMPUTE sobre todo ), obtendrás un informe que agrupe los
productos por su ID_comprador, listando la suma de Precios
después de cada grupo de productos de un ID_comprador, y ,
después que todos los grupos sean listados, la suma de todos
los Precios listados, todos con cabeceras y líneas generados
por SQL.
Además, algunos DBMS permiten usar
más funciones en listas Select, excepto que estas funciones
(algunas funciones de carácter permite resultados de múltiples
filas) vayan a ser usadas con un valor individual (no grupos),
en consultas de simples filas. Las funciones deben ser usada
sólo con tipos de datos apropiados. Aquí hay algunas funciones
Matemáticas:
Funciones
numéricas:
| ABS(X) |
Valor absoluto. Convierte número negativos
en positivos, o deja sólo números positivos. |
| CEIL(X) |
X es un valor decimal que será redondeado
hacia arriba. |
| FLOOR(X) |
X es un valor decimal que será redondeado
hacia abajo. |
| GREATEST(X,Y) |
Devuelve el más grande de los dos valores. |
| LEAST(X,Y) |
Devuelve el más pequeño de los dos valores. |
| MOD(X,Y) |
Devuelve el resto de X/Y. |
| POWER(X,Y) |
Devuelve X elevado a Y |
| ROUND(X,Y) |
Redondea X a Y lugares decimales. Si se omite
Y, X se redondea al entero más próximo. |
| SIGN(X) |
Devuelve menos si X<0, sino un más. |
| SQRT(X) |
Devuelve la raiz cuadrada de X. |
|
Funciones de Caracteres
| LEFT(<string,X) |
Devuelve los X caracteres más a la
izquierda de la cadena. |
| RIGHT(<string,X) |
Devuelve los X caracteres más a la
derecha de la cadena. |
| UPPER(<string) |
Convierte la cadena a mayúsculas. |
| LOWER(<string) |
Convierte la cadena a minúsculas. |
| INITCAP(<string) |
Convierte el primer carácter de la
cadena a mayúscula. |
| LENGTH(<string) |
Devuelve el número de carácteres de
cadena. |
| <string||<string |
Concatena dos cadenas de texto. |
| LPAD(<string,X,'*') |
Rellena la cadena por la izquierda
con el * (o el carácter que haya entre las comillas),
para hacer la cadena X caracteres más larga. |
| RPAD(<string,X,'*') |
Rellena la cadena por la derecha con
el * (o con el carácter que haya entre las comillas),
para hacer la cadena X caracteres más larga. |
| SUBSTR(<string,X,Y) |
Extrae Y letras de la cadena comenzando en
la posición X. |
| NVL(<column,<value) |
Cualquier Null de la <column será sustituido
por lo que haya en <value. Si el valor de la
columna no el NULL, NVL no tiene efecto |
|
CAPÍTULO 8. Resumen
de Sintaxis
Resumen de
Sintaxis. Sólo para usuarios
avanzados.
Aquí están las formas generales
de las sentencias que hemos visto en este tutorial, además
de alguno información extra de algunas. RECUERDA que todos
estas sentencias pueden o no pueden estar disponibles en tu
sistema, así que comprueba la documentación del mismo.
ALTER TABLE <TABLE
NAME ADD|DROP|MODIFY (COLUMN SPECIFICATION[S]...ver Create
Table);
Te permite añadir, borrar o modificar
una columna o columnas de la tabla, o cambiar la especificación
(tipo de datos, etc) de una columna existente; esta sentencia
también es usada para las especificaciones físicas de la tabla
(como está almacenada, etc.), pero estas definiciones estas
especificadas en el DBMS, así que léete la documentación.
También, estas especificaciones físicas son usada con la sentencia
Create Table, cuando una tabla es creada por primera vez.
Además, solo una opción puede ser realizada por la sentencia
Alter Table en una simple sentencia: add, drop o modificar.
COMMIT;
Hace cambios hechos por algún sistema
permanente de base de datos (desde el último COMMIT; conocido
por transacción)
CREATE [UNIQUE] INDEX <INDEX NAME
ON <TABLE NAME (<COLUMN LIST);
--UNIQUE es opcional; entre corchetes.
CREATE
TABLE <TABLE NAME
(<COLUMN NAME <DATA TYPE [(<SIZE)] <COLUMN
CONSTRAINT,
...otras columnas; (también valido con ALTER TABLE)
--donde SIZE sólo se utiliza en determinados tipos, y CONSTRAIN
incluye las siguientes posibilidades (forzado automático por
la DBMS; causas de fallos y generación de errores):
1.NULL o NOT NULL
(ver arriba)
2.UNIQUE fuerza que dos
filas no puedan tener el mismo valor para esa columna.
3.PRIMARY KEY le dice a
la base de datos que la columna es la columna clave primaria
(sólo usado si la clave primaria es sólo un columna, sino,
la sentencia PRIMARY KEY(columna, columna,...) aparece después
de la definición de la última columna)
4.CHECK permite que se comprueba
una condición cuando un dato es esa columna es actualizado
o insertado; por ejemplo, CHECK(PRECIO 0), hace que el sistema compruebe
que el precio de la columna es mayor de cero antes de aceptar
el valor... algunas veces implementado como sentencia
CONSTRAINT.
5.DEFAULT inserta el valor
por defecto en la base de datos si una fila es insertada sin
insertar ningún dato en la columna; por ejemplo: BENEFICIOS INTEGER DEFAULT=10000;
6.FOREIGN KEY hace lo mismo
que la clave primaria, pero es seguida por:: REFERENCES <TABLE NAME (<COLUMN NAME),
que hacen referencia a la clave primaria relacionada.
CREATE VIEW <TABLE NAME AS <QUERY;
DELETE FROM <TABLE
NAME WHERE <CONDITION;
INSERT INTO
<TABLE NAME [(<COLUMN LIST)]
VALUES (<VALUE LIST);
ROLLBACK; --deshace los
cambios en la base de datos que hallas hecho desde el último
Commit... cuidado! Algunos software usan automáticamente Commit’s
en sistemas que usan construcciones de transacción, así que
el comando RollBack podría no ir.
SELECT [DISTINCT|ALL]
<LISTA DE COLUMNAS, FUNCTIONES, CONSTANTES, ETC.
FROM <LISTA DE TABLAS OR VISTAS
[WHERE <CONDICION(S)]
[GROUP BY <GROUPING COLUMN(S)]
[HAVING <CONDITION]
[ORDER BY <ORDERING COLUMN(S) [ASC|DESC]];
--donde ASC|DESC permite ordenas en orden ASCendente
o
DESCendente
UPDATE <TABLE
NAME
SET <COLUMN NAME = <VALUE
[WHERE <CONDITION]; - si no
se completa la cláusula Where, todas las filas serán actualizadas
de acuerdo con la sentencia SET.
|