Resumen Teoría Parcial 2 BD (PDF)
Document Details
Uploaded by PraiseworthySagacity5299
UTN
Tags
Summary
Este documento resume la teoría de bases de datos, enfocándose en el modelo relacional. Explica conceptos como dominio, atributos, tipos de datos, relaciones y restricciones. Se abordan ejemplos prácticos para ilustrar la aplicación de estos conceptos.
Full Transcript
Modelo relacional: nos permite expresar conceptos del mer pero con un nivel ya superior de abstracción, los conceptos y vínculos los transformamos posteriormente. Una base de datos para el modelo relacional es una colección de relaciones. Aquí una relación significa una relación matemática e informa...
Modelo relacional: nos permite expresar conceptos del mer pero con un nivel ya superior de abstracción, los conceptos y vínculos los transformamos posteriormente. Una base de datos para el modelo relacional es una colección de relaciones. Aquí una relación significa una relación matemática e informalmente una tabla donde guardamos los datos que necesitamos. Las tablas están compuestas por filas, esas filas contienen una colección de valores que en conjunto representan un hecho del mundo real. Lo que en el Mer era una instancia de una entidad acá es una fila (un ejemplar) (una fila es tanto una entidad como vinculo que era en el mer). No existe el concepto de vinculo como tal, acá solo existen las relaciones. Columnas: además de las filas tenemos columnas que se entrelazan con las filas. En las columnas debe haber coincidencias con el tipo de dato almacenado en cada lugar, no puedo tener un desorden de filas y columnas en una misma columna todas las filas deben guardar el mismo tipo de dato. Conceptos: - Dominio Este término se refiere al conjunto de valores posibles que puede tomar una columna específica en una tabla (también llamado atributo). Los valores de un dominio son **atómicos**, lo que significa que no pueden dividirse más y representan la unidad mínima de información para ese atributo y ese valor posible no se puede dividir, es el mínimo valor presentable. - Tipos de datos: La manera más común de representar un dominio es a través de los tipos de datos Ej: cadena, entero, etc. El valor mínimo representable de un entero es el digito - Agrupación lógica: hay veces que es útil darles un nombre a los tipos de datos o hacer agrupaciones lógicas a esos tipos de datos subyacentes ej: Dni, num de teléfono, etc. Entonces al momento de definir el atributo de mi dominio o columna deja de ser un tipo abstracto como una cadena y se convierte en algo que tiene cierta lógica y que es mas entendible. Entonces en si en el tipo de dato yo voy a tener una columna nombre mi dominio será una cadena y n una cadena lo mínimo que puedo representar es un carácter. Pero si por ejemplo quiero representar los colores disponibles de un determinado producto entonces puedo definir un dominio que este compuesto por azul, rojo y verde y el valor atómico acá será una de estas posibilidades. Entonces es atómico en base a lo que yo defina para representar ese hecho. - Formato: Además de lo anterior se puede tener un formato que acompañe a los demás, en general cuando hay un formato existe un tipo de dato Ej: formato de los numero telefónicos. No es necesario que estos tres que conforman el dominio existan si o si, pueden existir uno, pero no el otro, aunque lo mínimo es que exista el tipo de dato Esquema de la relación Es la estructura o \"cabecera\" de una tabla, que define su nombre y los atributos (columnas) que la componen. Cada atributo está asociado a un dominio. Por ejemplo, en una tabla llamada Alumno con los atributos Legajo, Nombre y Teléfono, los dominios de esos atributos podrían ser entero para Legajo y cadena para Nombre y Teléfono. La lista de atributos es la que se vincula con el dominio R1(A1, A2,...An) siendo n la cantidad de columnas que va a tener Atributo: Un atributo en una tabla representa un rol específico de un dominio dentro de esa tabla. Por ejemplo, en el esquema de la tabla Alumno, el atributo Legajo juega el rol de \"identificador numérico del alumno\", mientras que Nombre representa \"nombre del alumno\". La asociación entre el atributo y el dominio se representa como D(Ai), donde Ai es el nombre del atributo y D(Ai) su dominio. Ej: Alumno (legajo: entero, Nombre:cadena, teléfono:cadena) donde alumno es el nombre de la relación, Legajo, nombre y teléfono son los atributos y entero y cadena los dominios del atributo respectivamente. Entonces el esquema es como la cabecera de la tabla y como está definida. Relación o estado de relación: Este es el conjunto de datos o \"tuplas\" que hay en la tabla en un momento específico. Cada tupla es una fila, y el conjunto de todas las tuplas conforma el estado actual de la relación (o la \"extensión de la relación\"). Por otro lado, el esquema de la relación (la cabecera de la tabla) se conoce como la \"intención de la relación\". Es decir r(R)={t1, t2,...tm} siendo m el numero de filas y r(R) el estado o la relación en si misma n-tuplas tj: Una tupla es una lista ordenada de valores (como una fila en una tabla), donde cada valor pertenece a un atributo específico y corresponde a su dominio. Por ejemplo, en una tupla \, el valor 1 corresponde al Legajo (con dominio entero), Juan al Nombre (con dominio cadena), y 123-4567 al Teléfono (también cadena). Representa una lista ordenada de n valores tj= \ es una lista ordenada de valores vi y n es la cantidad de columnas, m no es necesariamente debe coincidir porque la cantidad de coincidencias puede ser cualquiera, entonces voy a tener M tuplas pero cuando me meto en cada tupla en particular si o si cada tupla debe tener n valores. Coincide con la cantidad de columnas por eso coincide R(A1, A2,..., An) y además debe ser ordenada porque debe coincidir el tipo con cada columna Valor vi: Cada valor en una tupla debe pertenecer al dominio de su respectivo atributo, o puede ser nulo si no tiene un valor específico. Esto asegura que todos los valores de una columna respeten las restricciones de su dominio. Es decir dom(Ai) Grado de R: corresponde a la cantidad de atributos existentes en el esquema por lo que el grado es igual a n. Por ejemplo, en Alumno (Legajo, Nombre, Teléfono), el grado sería 3, ya que tiene tres atributos. Características de la relación: - Orden de las tuplas en R: En teoría de conjuntos, el orden de los elementos no importa, así que el orden en que se presentan las tuplas (filas) en un conjunto tampoco tiene importancia en el modelo relacional de bases de datos. En una base de datos real, sin embargo, sí existe un orden en el que las tuplas se muestran en una tabla, pero este orden es dado por la **implementación** del sistema y no afecta el significado de la relación. **Ejemplo**: Imaginemos una tabla Estudiantes que contiene los estudiantes de una clase. No importa si el estudiante \"Ana\" aparece primero y \"Carlos\" después, o viceversa; ambos están presentes en el conjunto, y el orden de aparición no afecta la información de la tabla en sí. Sin embargo, al visualizarlo en una base de datos, la lista de estudiantes puede aparecer en un orden específico, por ejemplo, ordenado por nombre o por fecha de ingreso. - Orden de los valores en cada tupla: Cada tupla en una relación debe tener un orden de valores específico, como \, que coincide con el orden de los atributos (columnas) en el esquema de la tabla. Este orden es importante porque permite que cada valor de la tupla se corresponda con el atributo adecuado en el esquema. Aunque en el diseño relacional el orden de las columnas no es fundamental, sí debe haber una coincidencia entre los atributos y los valores. **Ejemplo**: Supongamos que tenemos una tabla Empleados con columnas ID, Nombre, Teléfono. Una tupla como \ tiene sentido porque el valor 123 corresponde a ID, Juan a Nombre y 987654321 a Teléfono. Sin embargo, si el orden cambia a \, la información no tiene sentido sin una referencia clara, porque los valores no coinciden con sus atributos. Cuando se dice que \"no importa el orden que tenga si consigo tener una definición alternativa porque lo que realmente importa es que el atributo coincida con el valor\", se está refiriendo a que, en un modelo alternativo (como un conjunto de **mapeos**), el orden estricto de las columnas o los valores no es necesario siempre que cada valor se asocie correctamente con su atributo correspondiente. Esto quiere decir que podemos definir la relación de una forma que permita intercambiar el orden de las columnas sin perder el significado, porque cada valor sigue correspondiendo a su atributo. **Ejemplo Práctico** Imaginemos una tabla Empleados con tres columnas: - ID (Identificación) - Nombre (Nombre del empleado) - Teléfono (Número de teléfono del empleado) Una tupla en esta tabla podría ser: (123, \"Juan\", \"987654321\") En esta representación, el orden de los valores (ID, Nombre, Teléfono) importa, ya que el primer valor es el ID, el segundo el Nombre, y el tercero el Teléfono. Pero en un modelo de mapeo, podríamos representar esta tupla de la siguiente manera: {\"ID\": 123, \"Nombre\": \"Juan\", \"Teléfono\": \"987654321\"} Aquí, los valores están asociados explícitamente con sus atributos, por lo que el orden ya no importa: podríamos escribir {\"Teléfono\": \"987654321\", \"ID\": 123, \"Nombre\": \"Juan\"} y la relación seguiría teniendo el mismo significado, ya que cada atributo apunta al valor correcto. **En conclusión:** El orden de las columnas es importante en la estructura relacional típica porque no se incluye un mapeo explícito en cada tupla. Sin embargo, en un modelo alternativo, como el de un conjunto de mapeos, el orden de los valores se vuelve irrelevante, siempre que cada atributo tenga su valor correspondiente. - Valores en las tuplas: En el modelo relacional, los valores de las tuplas deben ser **atómicos**, es decir, cada casilla de la tabla tiene un solo valor indivisible (o un valor nulo si no hay un valor definido). No se permiten valores múltiples ni compuestos en una sola celda. **Nulo**: Un valor puede ser nulo si es inaplicable o desconocido: - **Inaplicable**: No existe ese valor para una entidad específica. Por ejemplo, un empleado puede no tener un título universitario, entonces su valor es nulo. - **Desconocido**: No conocemos el valor en ese momento, pero podría existir. Por ejemplo, el número de teléfono de un cliente puede ser nulo porque no se ha proporcionado aún. Otra razón es que puede ser desconocido que dentro de esta es porque hay un valor faltante o porque existe duda sobre su existencia, en el faltante estoy seguro que debe tener un valor, pero no se cual es, en el desconocido no estoy seguro si siquiera tiene un valor - **Ejemplo**: En una tabla de Clientes, si un cliente no tiene segundo nombre, la celda correspondiente al segundo nombre será nula para ese cliente. Esto no significa que todos los clientes deban tener ese campo vacío, solo que para ese cliente específico, el segundo nombre no aplica. - Interpretación: cada relación es una aserción/declaración de algo es decir que en mi modelo relacional, en el esquema de base de datos que estoy haciendo en base al modelo relacional cuando yo digo que un alumno tiene legajo, nombre, apellido y teléfono es porque siempre los alumnos se van a representar de esa manera en el modelo relacional en ese esquema en particular que estoy armando para mi dominio, son hechos que representan entidades o vínculos, cada tupla es una instancia de esa declaración/aserción Restricciones: - Dominio: todo valor posible debe ser atómico (un solo valor) - Clave: en un conjunto de tuplas cada una debe ser diferente, tiene que tener distintos valores, no puede existir 2 tuplas con igual combinación de valores para todos sus atributos esto es porque en un conjunto no puedo tener valores repetidos, la combinación debe ser distinta (combinación de cada casillero en la tupla). esto es general para todo estado de la relación r(R). 1. 2. - Resticcion de integridad de entidad: esta vinculada a la clave, todo valor en la clave primaria no debe ser nulo, no permite representar la entidad del mundo real si ese es el caso entonces si un atributo se define como clave todas sus tuplas en ese lugar deben tener algún valor no nulo - Integridad referencial: acá se habla de restricciones entre relaciones (tablas), para eso se utiliza la clave foránea, una tupla en una relación que haga referencia a otra relación debería referirse a una tupla existente en esa relación es decir que si digo que un alumno cursa TUP yo debo asegurarme de que en la entidad carrera exista como tupla (fila) el valor TUP. Si no existe la tupla correspondiente en la tabla referenciada (en este caso, la carrera TUP en la tabla carreras), **se violaría la integridad referencial (**relaciones entre tablas sean **coherentes y válidas)**. Esto implica que la base de datos no permitirá que la operación se complete, ya sea que se trate de una inserción o una actualización. Si la clave foránea tiene un valor nulo, la restricción de integridad referencial **no se aplica**. Esto significa que no es necesario que exista una fila correspondiente en la tabla referenciada. Si permites nulos, debes asegurarte de que el diseño de tu base de datos y las consultas posteriores contemplen la posibilidad de que estos valores no estén definidos. - Clave foránea: es un subconjunto de atributos. Entonces una FK entre los esquemas de relación R1 y R2 debe cumplir que: 1. Los atributos en FK de R1tienen los mismos dominios que los atributos de la clave principal pk de R2, los atributos Fk se dicen que referencia a la relación R2 es decir si la PK es entero (su dominio) la FK también 2. Un valor de Fk en una tupla t1 del estado actual r1(R1) o bien se representa como un valor de PK de alguna tupla t2 en r2(R2) o es null. En el primer caso tenemos que t1\[FK\] = t2\[PK\] y decimos que la tupla t1 se refiere a la tupla t2 (ósea que una fila refiere a otra fila y si tiene un valor nulo no existe esa referencia) habría una violación de la integridad referencial si por ejemplo la FK tiene un valor que no se encuentra en una columna de las pk de la otra tabla, la FK apunta a la PK Integridad referencial: La **integridad referencial** es una regla en bases de datos relacionales que asegura la consistencia de los datos al definir relaciones entre tablas. Su propósito principal es garantizar que cualquier referencia entre tablas sea válida, es decir, que no existan valores \"colgados\" o sin correspondencia. - **Clave foránea y su rol en la integridad referencial** Para implementar la integridad referencial, se utiliza un tipo de clave llamada **clave foránea (foreign key, FK)**. Una clave foránea es un atributo (o conjunto de atributos) en una tabla que **referencia la clave primaria** de otra tabla. La clave foránea asegura que cada valor que aparece en ella corresponda a un valor existente en la clave primaria de la otra tabla. Por ejemplo, en una base de datos que tiene dos tablas: Estudiantes y Cursos: - Estudiantes tiene una clave primaria ID Estudiante. - Inscripciones tiene una columna ID Estudiante como clave foránea que apunta a ID Estudiante en la tabla Estudiantes. **Reglas de integridad referencial** Para que la integridad referencial se cumpla, deben respetarse las siguientes reglas: 1. **Existencia de los valores**: - Cada valor en la clave foránea de la tabla que hace la referencia (en el ejemplo, la tabla Inscripciones) debe coincidir con un valor existente en la clave primaria de la tabla referenciada (Estudiantes). - Esto significa que no puedes tener un valor en Inscripciones en ID Estudiante que no exista en Estudiantes. Si intentas insertar un valor en Inscripciones sin un correspondiente ID Estudiante en Estudiantes, se violará la integridad referencial. 2. **Opciones de actualización y eliminación**: - Cuando se elimina o actualiza una tupla en la tabla referenciada (Estudiantes), se deben definir reglas sobre cómo esto afectará a la tabla que hace referencia (Inscripciones). - Estas reglas suelen ser: - **RESTRICT**: Prohíbe la eliminación o actualización si existen referencias. - **CASCADE**: Permite que la eliminación o actualización en la tabla referenciada se refleje en todas las tablas que la referencian. - **SET NULL**: Asigna un valor nulo en la clave foránea cuando la referencia en la tabla principal es eliminada. - **NO ACTION**: Similar a RESTRICT; solo que difiere en el tiempo en que se valida la restricción (a nivel de transacción). RESTRICT valida **inmediatamente**, justo en el momento en que se intenta ejecutar la operación. Si se detecta una violación, la operación falla de inmediato. En cambio, NO ACTION permite la operación **siempre que la integridad referencial quede intacta al final de la transacción**. **Ejemplo de integridad referencial** - - - - - 1. 2. 3. 4. - - - - 1. 2. 3. - - - - - - - Algebra relacional: Algebra relacional: es una colección de operaciones que sirven para modificar relaciones. Es la base de las consultas SQL - Consultas de obtención: son operaciones que sirven para obtener los datos de una tabla en una base de datos, la inserción, modificación y borrado se realizan con otro tipo de cláusulas, no con el algebra relacional. Cada operación del algebra relacional que hacemos es una operación que nos devuelve una nueva relación esa relación puede ser de un grado igual o diferente a la anterior (dif columnas) ej: OP(R)= R' donde OP(R) es la operación aplicada sobre una relación R y R' es la obtención de una nueva relación que puede ser de un grado mas chico, grande o igual que la relación original y una cantidad de filas variables. - Operación de selección: filtra las tuplas (filas) dentro de una relación, lo que hacemos es hacer una partición del tipo horizontal es decir de determinada relación lo que hacemos es tomar las filas que cumplen con la condición que estamos expresando, en el algebra relacional se lo expresa con la letra sigma ỽ ej: - Condiciones lógicas: Las condiciones dentro de la operación de selección deben expresarse de forma clara y deben evaluarse para cada fila de la relación. Ejemplo: σ₍año\_ingreso ≥ 2015 ∧ carrera = \'TUP\'₎(Alumno) - Unicidad de tuplas: La selección no duplica tuplas. Si dos tuplas cumplen la misma condición, ambas aparecerán en el resultado, sin duplicarse. - Restricciones de integridad referencial: Aunque la selección no afecta la integridad referencial directamente, puede restringir el resultado en caso de condiciones que filtren filas basadas en valores de claves primarias o foráneas. - Conmutatividad: La selección es conmutativa, lo que significa que el orden en el que se apliquen múltiples condiciones no afecta el resultado final. - Operación de proyección: a diferencia de selección realiza una partición vertical, es unaria pero no conmutativa, la proyección se representa con PI π - Restricciones de unicidad: La proyección elimina duplicados. Si seleccionas solo ciertas columnas y eso resulta en valores repetidos, las filas duplicadas serán eliminadas. - Orden de columnas (No Conmutatividad): La proyección no es conmutativa, ya que el orden importa cuando decides qué columnas incluir. - Preservación de la estructura de columnas: La proyección no puede incluir columnas que no están en la relación original, ya que esto generaría un error. Es decir, solo puedes proyectar columnas que realmente existan en la tabla inicial. - Operación de unión: la unión entre 2 relaciones genéricas R y S resulta en una nueva relación que incluye a todas las filas de la relación R y todas las filas de la relación S (va apilando) Es diferente al Join. R U S (en la unión saca los repetidos y solo los muestra una vez). Para aplicar las relaciones deben tener: - Operación de intersección: entre R y S resulta en una nueva relación que incluye las tuplas comunes a R y S (las tuplas comunes en las relaciones crean una nueva relación) todos los valores de los campos deben ser iguales R [∩]{.math.inline} S (en la intersección saca los que no son repetidos es que toma los que se encuentran en común de las 2 relaciones). - Resta: entre R y S resulta en una nueva relación que incluye todas las tuplas que están en S (R-S), Es decir, tomamos todas las filas de R y eliminamos las filas que son comunes con S. - Condición de unión: Las operaciones de unión, intersección y resta deben cumplir con la **condición de unión**, que se refiere a las siguientes restricciones: - **Mismo número de atributos**: Deben tener la misma cantidad de columnas. Esto significa que, si R tiene 3 columnas, S también debe tener 3 columnas. - **Mismos dominios**: Cada columna correspondiente en R y S debe tener el mismo tipo de dato. Por ejemplo, si una columna en R es un entero, la columna correspondiente en S también debe ser un entero. - **Mismo orden**: Las columnas deben estar en el mismo orden en ambas relaciones. Si en R la primera columna es id y la segunda es nombre, en S debe seguir el mismo orden. - **Flexibilidad en la compatibilidad**: Aunque R y S no sean inicialmente iguales, es posible aplicar operaciones como **proyección** (representada por π) para ajustar la estructura de una de las relaciones. Por ejemplo, si tienes una relación R con columnas A, B y C, y otra relación S con columnas A y B, puedes usar πA, B(R) para reducir R a las mismas columnas que S para que sean compatibles. - **Unión e intersección**: Ambas operaciones actúan sobre filas y devuelven una relación que puede incluir o excluir tuplas basadas en su presencia en ambas relaciones. - **Join**: A diferencia de la unión y la intersección, el join actúa sobre **columnas**, combinando filas de diferentes relaciones según una condición específica que conecta columnas de ambas. - Producto cartesiano: es la combinatoria de los elementos existentes de un conjunto y en el otro me da una combinatoria entre las relaciones, combina cada tupla de R con cada una de S se expresa como RXS. Es la base de del Join. - El número de filas en el resultado es el producto del número de filas de las dos relaciones. - No requiere que las dos relaciones tengan un atributo en común. - El producto cartesiano puede generar muchas combinaciones innecesarias si no se aplica un filtro (como una condición de **JOIN**) después. - Restricciones y consideraciones en el producto cartesiano: - Crecimiento exponencial: El número de filas en el resultado del producto cartesiano es el producto del número de filas en cada tabla. Si una tabla tiene 3 filas y otra tiene 4, el producto cartesiano tendrá 3×4=12 combinaciones. Con más tablas, este número crece rápidamente, lo que puede causar problemas de rendimiento si no se filtran adecuadamente las combinaciones. - No requiere que las tablas tengan columnas en común: El producto cartesiano no necesita que las tablas compartan atributos. Combina cada fila de la primera tabla con cada fila de la segunda, sin importar si tienen algo en común. - Uso eficiente con condiciones de filtrado: El producto cartesiano por sí solo genera muchas combinaciones irrelevantes en la mayoría de los casos. Para que sea útil, se suele aplicar junto con una condición de selección (JOIN) para filtrar las combinaciones que tengan sentido, por ejemplo, aquellas que coincidan en un atributo compartido. - Particularidades: si tengo las relaciones R y S siendo R (A1, A2,... An) X S (B1, B2,...Bm) es decir de una cantidad diferente con distintos atributos el resultado del producto cartesiano va a ser una nueva relación que va a tener n+m **columnas**. Es decir se crea una relación tal que Q\ - Tercera forma normal: dependencias transitivas es decir todos los atributos no claves deben depender de atributos claves solamente, no puede haber dependencia de otros atributos comunes. Una dependencia transitiva ocurre cuando un atributo no clave depende de otro atributo no clave en lugar de depender directamente de la clave primaria. Es como una cadena de dependencias: A → B → C Donde C es un atributo no clave que depende de otro atributo no clave (B), y B a su vez depende de la clave primaria A. Esta es la dependencia transitiva, porque C no depende directamente de A (la clave primaria), sino que pasa a través de B. Mapeo de Mer a MR: no se puede implementar el mer directamente porque es de más alto nivel, para ello lo pasamos al modelo relacional que son relaciones o tablas Mapeos: - Entidades fuertes: por cada entidad fuerte creamos una tabla y si en esa entidad fuerte existen atributos simples se los coloca todos y si existe compuestos se los debe desagregar es decir simplificar la estructura Ej: si nombre este compuesto por nombre de pila, paterno y materno entonces se crearán 3 atributos que se llamen: nombre de pila, nombre paterno y nombre materno. Por último, al atributo clave lo transformamos en clave primaria y si no existe le ponemos nosotros una clave además de que si la relación en el MER tiene un atributo a este se lo pondrá en la tabla que contenga la FK - Entidades débiles: va una tabla por cada entidad débil con todos los atributos simples y desagregando los atributos compuestos en simples, pero acá la clave primaria va a ser una combinación de la clave parcial + la clave primaria de la entidad fuerte que posee a la entidad débil, es decir que la clave primaria de la entidad fuerte será clave primaria y foránea en la entidad débil - Vínculos binarios: dependiendo de la cardinalidad general tienen una u otra forma de convertirse: - Binario (1:1): donde el máximo de ambos lados es 1. Acá se agrega cualquiera de las dos tablas para poner la FK aunque uno de los dos lados es mejor y esto es del lado que tenga (1:1) en el Mer, es decir una participación total y no (1:0), si ambos lados tiene (1:1) entonces no importara el lado que se lo coloque - binario (1:N): se escoge el lado N y se agrega la Pk del lado 1 como FK si es una relación débil se utiliza la formula de entidades débiles como se mostro mas arriba es decir que en el ER se pone la FK del lado contrario de donde esta la N en el Mer - Recursivo (1:N): parecido al anterior, lo que me puede ayudar es tomar como tablas a los nombres que se le ponen a los lados recursivos, entonces entre esas dos tablas ficticias pondré del lado contrario al N un FK que se llame como la tabla ficticia que tiene el (0:N) o (1:N) en el Mer - Recursivo (N:N): se crea una tabla con el nombre de la relación recursiva y se ponen dos claves primarias que serán compuestas y que a su vez serán claves foráneas y llevaran el nombre de las tablas ficticias - Vinculo (N:N): se debe crear una tabla nueva y se agregan las claves primarias de cada clave participante, en los extremos y esas claves primarias que formaran una PK compuesta en una nueva tabla que van a ser a su vez claves foráneas, también si la relación del Mer que contiene a este vinculo N:M tiene un atributo se lo pondrá en la tabla intermedia - Atributos multivaluados: se crea una nueva tabla y la clave primaria será el nombre del atributo multivaluado + la clave primaria de la entidad que contiene a ese atributo multivaluado en el Mer y que también seria FK en esa tabla - Vinculo n-ario: es decir con un n mayor a 2 como por ejemplo 3 o 4, es similar a (M:N). Entonces se crea una nueva tabla y se agrega las PK de cada tabla como PK y FK mas los atributos que tenga esa relación en el MER y también la tabla llevara el nombre de esa relación - Generalización y especialización (herencia): existen 4 formas dependiendo el tipo de herencia: -1) varias tablas que coincidan con la cantidad de supertipos y subtipos es decir si tengo cliente y subtipos cliente común y cliente preferencial tendré 3 tablas ![](media/image3.png) -2) varias tablas, pero solo para los subtipos es decir en este caso solo 2 tablas y los atributos en el supertipo se los ponen en las dos tablas de los supertipos, esta es aplicables solo cuando la restricción es de completitud total (doble línea \|\|) -3) una tabla para todo donde colocamos un atributo de tipo en la tabla esto solo se permite cuando la restricción de herencia es disjunta pero no solapado (que no sea "o" la restricción) ![](media/image5.png) Tipo de cliente es un atributo especial que agrego para saber si es cliente común o profesional -4) una tabla y varios atributos de tipo con el cual en esa tabla tengo todo junto, pero voy a poder marcar que tipo es esa tabla ósea que me podría permitir las dos al mismo tiempo (ser solapado) para ello debo agregar tantos campos como tipos existentes entonces para el ejemplo debería tener un campo cliente común y cliente preferencial los cuales serán booleanos donde puedo marcar a uno u otro y también ambos al mismo tiempo Se recomienda usar la opción 1 Entonces siguiendo con el ejemplo en cliente tendría DNI como PK y en cliente común y en cliente preferencial a DNI como PK y FK - Agregación: también parecido al vinculo (M:N) ya sea dentro o fuera de la agregación y la relación que esta por fuera de la agregación tendrá los campos claves de las entidades dentro de la agregación sumado a las entidades que estén relacionadas a estas EJ: ![](media/image7.png) Las relaciones serán: En reparar representara al vínculo individual y al agregado. Cuando se vincula con técnico y artefacto representa al vinculo y cuando se vincula con insumos representa la agregación que la contiene. En la tabla utiliza los atributos DniTecnico y NumArt son parte de la clave primaria junto con NumIns pero también serán una clave foránea compuesta que apunta a repara Clase 9: SQL server: es un gestor de base de datos relacional (RDBSM). Disponible para Windows y Linux, maneja desde pequeños a grandes volúmenes de datos Tipos generales: existen 3: - - Ediciones de SQL server: SQL Server tiene varias ediciones que ofrecen diferentes niveles de funcionalidad y limitaciones de uso. Estas ediciones permiten que tanto grandes empresas como pequeños desarrolladores encuentren una opción adecuada para sus necesidades. A continuación, se describen las principales ediciones de SQL Server: 1. **Enterprise**: Es la edición más completa, diseñada para empresas que requieren un alto rendimiento, alta disponibilidad, y características avanzadas de seguridad y análisis. Esta edición ofrece el máximo nivel de funcionalidades y es la menos restringida en términos de uso del hardware y la cantidad de recursos (CPU, memoria, almacenamiento) que puede manejar. Está pensada para grandes volúmenes de datos y aplicaciones de misión crítica. 2. **Standard y Web**: - **Standard**: Esta edición tiene muchas funcionalidades útiles, aunque más limitadas en cuanto a rendimiento y escalabilidad que la Enterprise. Es ideal para medianas empresas o para aplicaciones que no requieren todos los niveles avanzados de la Enterprise. - **Web**: Está optimizada para aplicaciones web y hosting, ofreciendo muchas de las funcionalidades de la edición Standard, pero adaptada específicamente para ambientes web. Esta edición es más accesible económicamente, lo que la hace adecuada para proveedores de servicios de alojamiento. 3. **Developer y Express**: - **Developer**: Es una edición gratuita que contiene todas las funcionalidades de la edición Enterprise, lo que permite a los desarrolladores construir y probar aplicaciones con las capacidades completas de SQL Server. Sin embargo, esta edición no está autorizada para entornos de producción, es decir, su uso está limitado a desarrollo y pruebas. - **Express**: También es gratuita y está diseñada para pequeños proyectos o aplicaciones con requerimientos mínimos. Esta edición tiene limitaciones en cuanto a la cantidad de recursos que puede usar (como CPU y memoria) y está pensada para proyectos personales, pequeñas aplicaciones y aprendizaje. Instancias: es una copia del ejecutable de SQLservr.exe. En SQL Server, una **instancia** es una copia independiente del motor de base de datos que se ejecuta como un servicio en el sistema operativo. Cada instancia opera como un motor separado en la misma máquina, permitiendo tener múltiples instancias de SQL Server que funcionan de manera autónoma y no interfieren entre sí, lo cual es útil para entornos de desarrollo, pruebas y producción en un solo servidor. **Instancias de SQL Server** 1. **Instancia por defecto y nombradas**: - **Instancia por defecto**: Al instalar SQL Server, se puede configurar una única instancia que funcione como \"por defecto\". Cuando configuramos una instancia como la predeterminada, no es necesario especificar un nombre al conectarse al servidor SQL, ya que se puede acceder simplemente usando el nombre del servidor o su dirección IP. - **Instancias nombradas**: A diferencia de la instancia por defecto, estas instancias adicionales requieren un nombre único. Al conectarse a una instancia nombrada, es necesario incluir el nombre de la instancia junto con el nombre del servidor o su IP en el formato servidor\\nombre instancia. 2. **Límites de instancias**: - Un servidor puede tener una sola instancia por defecto, pero puede tener hasta 50 instancias nombradas, permitiendo hasta 51 instancias en total en un único servidor. Esto es útil para ejecutar diferentes entornos o configuraciones de SQL Server en un mismo hardware sin interferencias. 3. **Conexiones a instancias**: - Cuando se conecta a la **instancia por defecto**, se puede acceder directamente sin especificar el nombre de la instancia, por ejemplo, localhost. - Para conectarse a una **instancia nombrada**, el nombre de la instancia debe indicarse al final del nombre del servidor, por ejemplo, localhost\\InstanciaNombrada. Base de datos: Dentro de cada instancia, se pueden crear múltiples bases de datos. Las bases de datos son contenedores lógicos donde se almacenan los datos y los objetos necesarios para trabajar con ellos. Los límites y estructura de una base de datos son los siguientes: 1. **Límite de bases de datos por instancia**: Cada instancia de SQL Server puede albergar hasta 32,000 bases de datos teóricamente y dentro de la BD tenemos las tablas o cualquier otro objeto que por objeto nos referimos a tablas, vistas, procedimientos almacenados, funciones, etc. Aunque en la práctica, este número puede variar en función de los recursos del sistema - Dentro de una base de datos, se encuentran **objetos** como: - **Tablas**: Almacenan los datos en formato estructurado, organizados en filas y columnas. - **Vistas**: Son consultas guardadas que actúan como tablas virtuales y muestran datos combinados de una o más tablas. - **Procedimientos almacenados**: Son programas almacenados que contienen código SQL que ejecuta una serie de instrucciones, útil para operaciones repetitivas. - **Funciones**: Devuelven un valor y pueden ser usadas para realizar operaciones en los datos. - Estos objetos permiten estructurar, manipular y consultar los datos dentro de la base de datos. - La **instancia por defecto** se utiliza para el ambiente de producción, donde las aplicaciones acceden directamente a la base de datos principal. - Una **instancia nombrada** para el ambiente de pruebas, por ejemplo, Servidor\\Pruebas, donde se pueden replicar datos o probar cambios sin afectar el entorno de producción. - Otra **instancia nombrada** llamada Servidor\\Desarrollo para el equipo de desarrollo, donde se pueden realizar experimentos y ajustes en nuevas versiones de las bases de datos. Es decir: ![](media/image9.png) Tipos generales: existen 2 tipos generales de bases de datos: - Usuario: Son aquellas creadas directamente por los usuarios. Estas bases contienen datos y objetos personalizados según las necesidades de una aplicación o proyecto en particular. Los usuarios tienen control total sobre el diseño de estas bases de datos y sus objetos. - Sistema: Estas son bases de datos que SQL Server crea automáticamente para el funcionamiento interno del motor de base de datos. Son esenciales para la administración de SQL Server ya que contienen información crítica para el funcionamiento del sistema. SQL Server tiene cinco bases de datos de sistema principales: - Master (metadatos): Esta es la base de datos central y la más importante de SQL Server, ya que almacena metadatos esenciales al nivel de la instancia. En la base *master* se encuentran las configuraciones generales y los metadatos de todas las bases de datos de usuario y del sistema, no tendré muchas tablas, pero si muchas vistas a las que puedo acceder porque en realidad hay una base de datos oculta que no se muestra que es la base de datos resourse (base de datos interna) que es la que contiene los esquemas y la master consulta a esa para obtener los metadatos. Esta estructura ayuda a SQL Server a consultar información sobre las configuraciones y objetos de todas las bases de datos instaladas. Cada instancia de SQL Server tiene su propia base de datos **master**, que contiene los metadatos y configuraciones específicas para **esa instancia en particular**. - Resourse (oculta el real sys Schema): Esta base de datos, oculta al usuario, contiene todos los esquemas y las definiciones de objetos del sistema. Actúa como una base interna que la *master* utiliza para consultar la estructura de SQL Server (esquema de sistema). Aunque no es accesible directamente, su información es vital para el funcionamiento general y las operaciones de SQL Server, proporcionando el \"verdadero catálogo del sistema\". **catálogo del sistema** se refiere a un conjunto de tablas, vistas y estructuras internas que almacena metadatos sobre todos los objetos y configuraciones dentro de SQL Server (nombres, estructuras, índices, **Vistas**, **procedimientos,** claves primarias y foráneas) - Model (plantilla de creación): Esta base de datos actúa como una plantilla para todas las bases de datos nuevas que se crean en SQL Server. Cualquier objeto o configuración en la base *Model* se replica en cada nueva base de datos que se cree en el servidor. Por ejemplo, si se agrega una tabla llamada TablaX en *Model*, cada nueva base de datos tendrá una copia de esa tabla de forma predeterminada. - tempDB (tablas temporales): Esta base de datos es temporal y se utiliza para almacenar datos y objetos temporales, como tablas temporales y resultados de consultas intermedias. La *tempDB* se recrea cada vez que se reinicia el servidor SQL y es esencial para cálculos o procesamiento temporal de datos. Las operaciones que no requieren almacenamiento a largo plazo suelen aprovechar esta base para mejorar el rendimiento. - MSDB (ss agent) Esta base es utilizada por el agente de SQL Server (SQL Server Agent) para almacenar datos sobre la programación de trabajos automatizados, alertas y mantenimiento de tareas. Por ejemplo, si se programa una tarea para realizar un respaldo diario de una base de datos, esta configuración y su historial de ejecución se almacenan en *MSDB*. Estos 5 conforman la base de datos del sistema que se genera con SQL server Catálogo de metadatos en SQL Server En SQL server el catalogo esta repartido, es decir: una parte esta en el master que son los metadatos a nivel de instancia es decir es un intermediario para acceder a la información de los metadatos que se encuentran en resourse, pero a nivel de instancia es decir que en resourse puedo consultar cuantas instancias de BD hay, cuáles son sus nombres, etc. Haciendo una consulta SQL y en los archivos de usuarios cada vez que genero una BD se guardan información sobre los metadatos de esa BD en particular Es decir: SQL Server maneja un sistema de **catálogo distribuido de metadatos**: - **Nivel de instancia**: La base *master* actúa como el \"directorio\" de SQL Server, almacenando metadatos generales sobre la instancia, como nombres de las bases de datos, configuraciones de seguridad, etc. Sin embargo, no contiene los detalles de los objetos individuales dentro de cada base, sino que actúa como intermediario para acceder a la información almacenada en la base *Resource*. - **Nivel de base de datos**: Cada base de datos de usuario mantiene su propio catálogo de metadatos sobre sus objetos (tablas, vistas, procedimientos, etc.), almacenado en sus archivos propios. Esto significa que cada vez que se crea una base de datos, su propio esquema y metadatos se almacenan en sus archivos, permitiendo que SQL Server administre de forma independiente cada base de datos sin mezclar sus configuraciones y estructuras. Archivos: En SQL Server, al crear una base de datos se generan archivos físicos que almacenan tanto los datos como el registro de transacciones. Los archivos predeterminados de una base de datos son el **MDF** (archivo de datos principal) y el **LDF** (archivo de registro de transacciones), pero se pueden agregar archivos adicionales, como el **NDF**, para gestionar el crecimiento de la base de datos y optimizar el rendimiento. También se organizan en **Filegroups** para facilitar la administración y el almacenamiento eficiente de datos. - MDF (master data file): Es el archivo principal de la base de datos, en el que se almacenan tanto los datos como el esquema de los objetos de SQL Server (tablas, vistas, procedimientos almacenados, etc.). Al crear una base de datos, siempre se genera un archivo MDF, que es el archivo fundamental para el almacenamiento de datos. Es el archivo que se encarga de guardar los datos y el esquema de la base de datos es decir a lo que llamamos objetos en SQL server - Log LDF (load data file): es donde se va a guardando la información de recuperación acerca de las transacciones que se van ejecutando en esa base de datos en particular, lo que permite recuperar datos en caso de fallo y asegura la consistencia en las operaciones. Este archivo es crucial para realizar restauraciones o revertir transacciones en caso de errores. - NDF (Not Demand Data File): es un archivo secundario, sirve para guardar datos allí permitiendo que la bd crezca en el tiempo y lo haga de manera optima o teniendo buena performance esto es para la bd con muchos accesos concurrentes es decir muchas cargas de trabajo. Este archivo es opcional y se usa principalmente en bases de datos con altos volúmenes de datos o muchas transacciones concurrentes, distribuyendo la carga entre varios archivos para mejorar el rendimiento. - **Ejemplo de optimización**: Si hay tablas que reciben muchas transacciones, podemos almacenarlas en archivos separados y colocarlos en discos físicos diferentes. Esto permite que los discos trabajen de forma independiente, mejorando la eficiencia del acceso a datos. - Filegroups: es otra opción que ofrece SQL server, de entrada, me obliga a tener uno si o si que es el primario que contiene al archivo MDF y además puede tener otros archivos como el Filegroup 1 y 2 y que tienen, también puedo crear uno secundario, esto se hace porque suponiendo que tengo mi archivo primario A1 y mi conjunto de archivos secundarios A2 y A3. Entonces cuando voy a crear una tabla lo puedo hacer en el archivo primario o en los secundarios por lo que lo que estoy haciendo no es crear una tabla en tal archivo si no que en un grupo lo voy a asignar. Entonces lo más usado es el MDF y LDF porque la mayoría de las veces es suficiente con ellos y opcionalmente puedo crear archivos secundarios y colocarlos en grupos donde el grupo primario es el que se toma por defecto si yo no defino un lugar en donde colocar mis tablas, pero siempre debe existir uno de ellos - Filegroup Primario: - Filegroups secundarios: - Características: Esquemas y objetos: En SQL Server, un **esquema** es un contenedor o \"carpeta\" que organiza y agrupa los objetos dentro de una base de datos. Los objetos en SQL Server, como tablas, vistas, procedimientos almacenados, entre otros, no están directamente en la base de datos, sino dentro de esquemas. Los esquemas cumplen dos funciones principales: **Funciones de un esquema** 1. **Organización y estructura**: - Los esquemas actúan como carpetas para clasificar los objetos. Esto es especialmente útil cuando una base de datos tiene muchos objetos relacionados con diferentes áreas o departamentos de la organización, como Ventas (Sales), Recursos Humanos (HR), Finanzas, etc. - Al agrupar los objetos en esquemas, se mejora la claridad y la facilidad de gestión. Por ejemplo, en lugar de mezclar todas las tablas, podemos organizarlas en esquemas específicos: - Esquema Sales para tablas relacionadas con ventas, como Sales.Orders o Sales.Customers. - Esquema HR para tablas de recursos humanos, como HR.Employees o HR.Salaries. 2. **Gestión de permisos y seguridad**: - SQL Server permite establecer permisos sobre esquemas completos, lo que simplifica la administración de acceso a los objetos. - Esto significa que, en lugar de asignar permisos a cada tabla de manera individual, podemos asignarlos al esquema, y todos los objetos dentro de ese esquema compartirán el mismo nivel de acceso. - **Ejemplo**: Si un usuario solo necesita acceso a la información de ventas, se le pueden otorgar permisos sobre el esquema Sales, y automáticamente podrá acceder a todas las tablas y objetos en ese esquema sin necesidad de configurar permisos uno por uno. **Esquema predeterminado dbo** Cuando se crea una base de datos en SQL Server, se genera automáticamente un esquema predeterminado llamado **dbo** (Database Owner). Este esquema es el más común y se utiliza a menudo como contenedor general para los objetos en una base de datos. Sin embargo, SQL Server permite crear esquemas adicionales para una mejor organización y administración. Importación DTS: **Características de DTS** 1. **Importación y exportación de datos**: Permite mover datos desde una base de datos de origen hacia una base de datos de destino, dentro de SQL Server o hacia/dentro de otros sistemas de datos. 2. **Transformación de datos**: Realiza transformaciones en los datos mientras se mueven, como el cambio de tipos de datos, el cálculo de valores, la combinación de datos de múltiples fuentes, entre otras operaciones. 3. **Automatización de tareas**: DTS permite automatizar las tareas de importación/exportación mediante el uso de paquetes DTS. Estos paquetes contienen una serie de pasos o tareas que se ejecutan en orden para realizar operaciones de transferencia y transformación de datos. **Uso de DTS en la práctica** **DTS en versiones posteriores de SQL Server** Clase 10 SQL es un lenguaje de programación estándar utilizado para gestionar y manipular bases de datos relacionales. Se clasifica en varios sublenguajes que permiten realizar diferentes tipos de operaciones sobre la base de datos: 1. **DDL (Data Definition Language)**: Se ocupa de la definición y estructura de la base de datos. Las sentencias DDL permiten crear, modificar y eliminar objetos en la base de datos. Incluyen: - **CREATE**: Se utiliza para crear nuevos objetos, como bases de datos, tablas, índices, etc. - **ALTER**: Se utiliza para modificar la estructura de un objeto existente, como agregar o eliminar columnas de una tabla. - **DROP**: Se utiliza para eliminar objetos de la base de datos, como tablas, vistas o bases de datos completas. 2. **DML (Data Manipulation Language)**: Se ocupa de la manipulación y el acceso a los datos dentro de las estructuras definidas por DDL. Las sentencias DML permiten realizar operaciones de lectura y escritura en las tablas. Incluyen: - **SELECT**: Se utiliza para consultar y recuperar datos de una o más tablas. - **INSERT**: Se utiliza para agregar nuevos registros a una tabla. - **UPDATE**: Se utiliza para modificar registros existentes en una tabla. - **DELETE**: Se utiliza para eliminar registros de una tabla. 3. **DCL (Data Control Language)**: Se utiliza para controlar el acceso a los datos en la base de datos. Permite gestionar los permisos y los roles de los usuarios. Incluye: - **GRANT**: Se utiliza para conceder permisos a los usuarios o roles sobre objetos de la base de datos. - **REVOKE**: Se utiliza para quitar permisos previamente otorgados a los usuarios o roles. TSQL DDL:\ las sentencias **DDL** (**Data Definition Language**) se utilizan para definir y administrar los objetos que forman parte de la estructura de una base de datos. Estas instrucciones son esenciales para la creación, modificación y eliminación de los objetos de base de datos. Sentencias DDL: 1) ![](media/image14.png) Por cada bd crea los archivos mdf y ldf siendo el mdf perteneciente al grupo de archivos primario, también puedo agregar un grupo secundario en el cual puedo establecer ciertos archivos como por ejemplo para performance 2) 3) ![](media/image16.png) 4) el prefijo dbo. es el esquema de la base de datos y es utilizado para especificar el esquema al que pertenece la tabla. dbo es el esquema predeterminado en SQL Server, que representa al \"database owner\" o propietario de la base de datos. Cuando se escribe dbo.Employee, estás indicando explícitamente que la tabla Employee pertenece al esquema dbo. Esto puede ser útil cuando: 1. **Existen múltiples esquemas**: Si en la base de datos tienes tablas con el mismo nombre en diferentes esquemas, como sales.Employee y hr.Employee, dbo.Employee ayuda a SQL Server a identificar específicamente a qué tabla te refieres. 2. **Mejora el rendimiento de consultas**: Especificar el esquema puede ayudar a SQL Server a encontrar la tabla más rápido, ya que evita que tenga que verificar en otros esquemas. 3. **Evita ambigüedades**: Aunque Employee podría funcionar sin dbo. si es el esquema predeterminado, es una buena práctica incluirlo para evitar ambigüedades y asegurar que la consulta funcione correctamente si la base de datos se mueve o se utiliza en un contexto diferente. Recordando que: Un **esquema** en una base de datos es una forma de organizar y agrupar objetos relacionados, como tablas, vistas, procedimientos almacenados, funciones y otros elementos dentro de la base de datos. Los esquemas ayudan a estructurar y administrar la base de datos de manera más ordenada y segura. En SQL Server (y en otros sistemas de gestión de bases de datos), un esquema es similar a una \"carpeta\" o \"contenedor\" que organiza estos objetos bajo un nombre común. Cada objeto (tabla, vista, etc.) pertenece a un esquema específico. Por ejemplo, en SQL Server, el esquema predeterminado es dbo (abreviatura de **database owner** o \"propietario de la base de datos\"). ### Ventajas de usar esquemas 1. **Organización**: Facilita el manejo de una base de datos compleja agrupando objetos relacionados bajo un mismo esquema. 2. **Seguridad**: Puedes otorgar permisos de acceso a usuarios específicos en determinados esquemas, permitiendo o restringiendo el acceso a ciertas áreas de la base de datos. 3. **Claridad**: Ayuda a evitar confusiones y nombres de objetos duplicados. Si tienes una tabla Clients en el esquema sales y otra en hr, se pueden distinguir como sales.Clients y hr.Clients. 4. **Mantenimiento**: Hace que el mantenimiento de la base de datos sea más sencillo, ya que puedes trabajar en un esquema específico sin interferir en otros Dato: no se puede cambiar el nombre de una columna con T-SQL pero si de forma grafica Para crear un esquema en SQL Server, utilizas el comando CREATE SCHEMA:\ CREATE SCHEMA sales; TSQL DML: la cláusula más destacada es select y otras importantes son insert, update y delete. Select es para consultas no destructivas e insert, update y delete pueden cambiar los datos en la bd. ![](media/image18.png) Table: Es decir que table se puede usar en select, insert, update y delete ej: select \* Fom nombreTabla. Entonces yo puedo invocar tablas dentro de select, insert, update y delete es decir hacer un select de ciertas columnas en una tabla en particular o insertar filas en una tabla en particular, actualizar o borrar filas de una tabla (select table; insert table; update table; delete table) Entonces: ### Ejemplos de cómo funcionan: - view: Una **vista** es una consulta guardada o \"empaquetada\" que se trata como una tabla virtual. Es decir, cuando defines una vista, no estás almacenando los datos en la base de datos como en una tabla regular; en cambio, guardas una consulta que se ejecuta cada vez que accedes a esa vista. - - ### Usar una vista Procedure: no puedo utilizar dentro de un select pero si dentro de un procedure utilizar la sentencia select - - - - - - ### Crear un procedimiento almacenado CREATE PROCEDURE **Obtenerempleadosporedad** (\@edad\_minima *INT*)\ AS\ BEGIN\ SELECT nombre,\ edad\ FROM empleados\ WHERE edad \= \@edad\_minima;\ END; En este ejemplo: - El procedimiento ObtenerEmpleadosPorEdad toma un parámetro (\@edad\_minima), que es la edad mínima que debe tener un empleado para aparecer en el resultado. - Este procedimiento ejecuta una consulta SELECT sobre la tabla Empleados para devolver todos los empleados cuya edad sea mayor o igual a la especificada. Entonces puedo utilizar select dentro de un procedimiento, pero no un procedimiento dentro de una sentencia select ### Usar SELECT, INSERT, UPDATE, y DELETE dentro de un procedimiento almacenado #### Ejemplo de procedimiento con INSERT, UPDATE, y DELETE Function: Una **función** en el contexto de bases de datos es un conjunto de instrucciones SQL que se puede almacenar y ejecutar en la base de datos para realizar operaciones específicas. Las funciones se utilizan para encapsular la lógica que puede ser reutilizada en diferentes partes de la aplicación o en consultas SQL. ### Características de las Funciones 1. **Retorno de Valor**: A diferencia de los procedimientos almacenados, que pueden realizar operaciones sin devolver un valor, las funciones siempre devuelven un resultado (que puede ser un único valor o una tabla, dependiendo del tipo de función). 2. **Uso en Consultas**: Las funciones pueden ser utilizadas en cualquier lugar donde se pueda usar una expresión, incluidas las cláusulas SELECT, WHERE, ORDER BY, etc. 3. **Parámetros**: Las funciones pueden recibir parámetros de entrada que les permiten recibir valores desde el exterior, procesarlos y devolver un resultado. 4. **Encapsulación de Lógica**: Permiten agrupar operaciones comunes y reutilizarlas, lo que mejora la legibilidad y el mantenimiento del código. ### Tipos de Funciones 1. **Funciones Escalares**: Devuelven un solo valor (como un entero, un decimal, una cadena, etc.). Estas funciones pueden ser utilizadas directamente en las consultas. 2. **Funciones de Tabla**: Devuelven un conjunto de filas (una tabla) y pueden ser utilizadas en la cláusula FROM de una consulta SQL. ### Consideraciones al Usar Funciones - **Rendimiento**: Las funciones pueden afectar el rendimiento si realizan cálculos complejos o se utilizan en grandes conjuntos de datos. - **Efectos Secundarios**: A diferencia de los procedimientos, las funciones deben ser \"determinísticas\", lo que significa que deben devolver el mismo resultado si se les pasan los mismos argumentos. No deben modificar datos en la base de datos (en el caso de funciones escalares). ### Uso de Sentencias SQL Dentro de Funciones Dentro de una función, puedes incluir sentencias SELECT, pero hay algunas restricciones: - **SELECT**: Puedes usar SELECT para recuperar datos y devolver resultados. Por ejemplo, puedes usar SELECT para calcular un valor y luego retornarlo: Clausula Select: el lenguaje SQL fue desarrollado para ser declarativo y por conjuntos entonces es útil para tratar ese tipo de problemas, esta pensado para tratar conjuntos de datos no para ejecución secuencial o tratar los registros de a uno y combinar elementos los elementos dentro de corchetes (\[\]) indican que esos elementos son **opcionales** en una consulta SELECT. Esto significa que puedes incluirlos o no, según tus necesidades. Explicación de cada uno de los elementos dentro de corchetes en el ejemplo: 1. **INTO tabla\_nueva**: - Si se incluye, permite crear una nueva tabla con el nombre tabla\_nueva y almacenar en ella los resultados de la consulta SELECT. - Ejemplo: SELECT nombre, edad INTO nueva\_tabla FROM empleados; - Si no se incluye, los resultados simplemente se mostrarán sin crear una nueva tabla. 2. **FROM tablas\_origen**: - Indica la tabla o tablas de las cuales se va a obtener la información. - Ejemplo: SELECT \* FROM empleados; - Es opcional en el caso de que no se necesite información de una tabla, como cuando se hace una consulta de una expresión matemática simple (SELECT 1 + 1;). 3. **WHERE condición\_búsqueda**: - Filtra las filas que cumplen una condición específica. - Ejemplo: SELECT \* FROM empleados WHERE edad \> 30; - Es opcional si deseas ver todos los datos sin ninguna condición. 4. **GROUP BY expresión\_group\_by**: - Agrupa los resultados según una o más columnas. - Ejemplo: SELECT departamento, COUNT(\*) FROM empleados GROUP BY departamento; - Es opcional y solo se usa si necesitas agrupar los datos. 5. **HAVING condición\_búsqueda**: - Filtra los resultados después de aplicar un GROUP BY. - Ejemplo: SELECT departamento, COUNT(\*) FROM empleados GROUP BY departamento HAVING COUNT(\*) \> 5; - Es opcional y solo se usa en combinación con GROUP BY para aplicar condiciones en los grupos. 6. **ORDER BY expresión\_order\_by \[ASC \| DESC\]**: - Ordena los resultados de la consulta en forma ascendente (ASC) o descendente (DESC). - Ejemplo: SELECT \* FROM empleados ORDER BY edad DESC; - Es opcional; si no se incluye, los resultados no tendrán un orden específico. Ejemplos: 1) ![](media/image26.png) 2) ![](media/image28.png) 3) ![](media/image30.png) Operadores aritméticos y su presidencia: ![](media/image32.png) Clase 11: Distinct: trata de traer solamente las filas distintas de la columna, sirve cuando no selecciono toda la tabla completa (\*), además la ordena Where: sirve para filtrar una o mas filas y retornara las filas donde la expresión lógica sea true, puedo hacerla tan compleja como quiera mientras el resultado de la expresión lógica sea true o false ![](media/image34.png) Operadores de comparación lógicos: And y between: son lo mismo e incluyen los valores limites dentro de su rango es decir son como =\< y \>= ![](media/image36.png) Aparear tablas sin join usando Where: ![](media/image38.png) Tabla resultante: ![](media/image40.png) Top: puede indicar la cantidad absoluta de filas (usando top N siendo este un numero natural) o también la cantidad relativa con Top Q \[percent\] \[with ties\] siendo ties un ordenamiento con valores repetidos es decir no excluye los valores repetidos que también pueden estar en top N Usando with ties: ![](media/image42.png) Offset fetch: es para hacer paginados ![](media/image44.png) In: es como un or contrasta una expresión contra un conjunto de valores (dentro de in puedo anidar consultas) Like: es para hacer una comparativa por aproximación contra una cadena para ver si cumple con un determinado patron, no es por igualdad, puede tener comodines como %, \[\], \_ y \[\^\] ![](media/image46.png) ![](media/image48.png) Not like cumple la misma función que \[\^\] ![](media/image50.png) Null: en T-SQL maneja distinta a los nulls, en una expresión lógica no solo puede ser verdadero o falso, sino que también unknown para si estoy haciendo una consulta en el where pongo or is null para que también me muestre los null o is not null si quiero que los oculte ### Resumen 1. En T-SQL, las expresiones pueden ser TRUE, FALSE, o UNKNOWN. 2. Cualquier comparación con NULL resulta en UNKNOWN. 3. Para trabajar con NULL, se usan IS NULL y IS NOT NULL. 4. OR IS NULL en una condición permite incluir filas con NULL en el resultado. 5. IS NOT NULL excluye las filas con NULL de los resultados. Funciones SQL: Pueden ser funciones incluidas o hechas por el usuario: - F usuario: puede ser escalar, devolver una tabla (tabular en línea) o multisentencia - F incluidas: ya vienen dentro de sql server, dentro de las incluidas pueden ser f escalares, agregación, etc - F escalares: Operan sobre un solo valor y devuelven un solo resultado. dentro de esta hay muchas como las matemáticas, cadenas, fechas, etc F matemáticas: ![](media/image52.png) F cadenas: La primera al concatenar null dará de resultado un null, pero con CONCAT omitirá el null ![](media/image54.png) Fechas: hay 6 tipos para representarlos, no existe una forma de representar un periodo de tiempo por lo que se lo representa mediante strings. Los 6 tipos principales de datos para manejar fechas en T-SQL son: 1. **DATE**: Representa una fecha sin la hora. Su formato es YYYY-MM-DD (4 dígitos para el año, 2 para el mes y 2 para el día). 2. **TIME**: Representa solo la hora, sin fecha. Su formato es HH:MM:SS.sss (hora, minuto, segundo y fracción de segundo opcional). 3. **DATETIME**: Representa una fecha y una hora con una precisión de hasta 3 milisegundos. El formato es YYYY-MM-DD HH:MM:SS.sss. 4. **SMALLDATETIME**: Similar al DATETIME, pero con menos precisión, hasta el minuto. El formato es YYYY-MM-DD HH:MM:SS. 5. **DATETIME2**: Similar al DATETIME, pero con una mayor precisión en los segundos y también puede incluir nanosegundos. Su formato es YYYY-MM-DD HH:MM:SS.nnnnnnnn (hasta 7 dígitos para los nanosegundos). 6. **DATETIMEOFFSET**: Es una variante de DATETIME2 que también incluye el desplazamiento de la zona horaria. Su formato es YYYY-MM-DD HH:MM:SS.nnnnnnnn +HH:MM (donde +HH:MM indica el desplazamiento de la zona horaria). ### Nanosegundos y tamaño variable El tipo **DATETIME2** es el que puede almacenar nanosegundos (hasta 7 dígitos de precisión en los segundos). La precisión de este tipo de dato es configurable al momento de definir la columna, permitiendo un valor entre 0 y 7 para la cantidad de dígitos fraccionarios que se almacenarán en la fecha y hora. Debido a que la precisión en los nanosegundos es variable (puede ir de 0 a 7 decimales en la fracción de segundo), el tamaño de almacenamiento de un campo **DATETIME2** también varía. Esto se debe a la cantidad de espacio necesario para almacenar la fracción de segundo. A continuación, te doy una descripción del almacenamiento de **DATETIME2** según su precisión: - **DATETIME2(0)**: No almacena fracción de segundo (tiene una precisión de solo segundos). Usa 6 bytes de almacenamiento. - **DATETIME2(1-2)**: Usará 7 bytes de almacenamiento. - **DATETIME2(3-4)**: Usará 8 bytes de almacenamiento. - **DATETIME2(5-7)**: Usará 9 bytes de almacenamiento. Esto significa que cuando se define una columna de tipo **DATETIME2**, su tamaño en bytes no es fijo, sino que depende de la precisión de los nanosegundos que se elijan. A mayor precisión, más espacio de almacenamiento será necesario. Joins: no son operaciones de conjuntos, son aparear filas, los tipos de join son 3: Cross join, Inner Join y Outer Join Inner Join: aparea filas de 2 tablas que cumplen una condición de clausula ON que es el criterio o condición de apareamiento ![](media/image56.png) Existen 2 tipos de inner Join: - Theta Join: dentro de él las condiciones de apareamiento son explicitas y se subdivide en otras 2: - EquiJoin: El **EquiJoin** es una forma específica de Theta Join en la que la condición de emparejamiento es una igualdad. En SQL, el operador de igualdad es =. - **Non EquiJoin** es un tipo de Theta Join en el que la condición de emparejamiento **no utiliza una igualdad (=)**. En lugar de eso, usa otros operadores de comparación (\, \=, \). Este tipo de join no es tan común como el EquiJoin, pero es útil en ciertos casos, como cuando deseas emparejar rangos de valores. - Natural Join: El **Natural Join** es otro tipo de INNER JOIN en el que **no se especifica explícitamente una condición de emparejamiento**. En cambio, el NATURAL JOIN empareja automáticamente las filas de las tablas basándose en todas las columnas con el mismo nombre y tipo en ambas tablas. ¿Por qué no se usa Natural Join en SQL Server? SQL Server no soporta directamente el NATURAL JOIN, ya que este join puede ser ambiguo y, en ciertos casos, puede producir resultados inesperados si las tablas contienen múltiples columnas con nombres coincidentes. En lugar de NATURAL JOIN, SQL Server requiere que se especifique la condición de emparejamiento mediante ON, proporcionando una mayor precisión y claridad sobre cuáles columnas deben ser emparejadas. Outer Join: en el inner join solo queríamos las filas que coinciden de ambos lados, en outer join queremos los que coinciden y también las que no, dentro de los outer join existen 3 tipos: - Left outer join: toma las filas que cumplan la condición, pero además las filas de la izquierda que no coinciden - Right outer join: igual que left join pero para las filas de la derecha - Full outer join: es un left y right sumados, aparea filas de dos tablas que cumplen con alguna condición y además devuelve todas las filas de la izquierda y derecha que no coinciden ¿Por qué no es lo mismo que un producto cruzado? El **FULL OUTER JOIN** no es lo mismo que un **producto cruzado** (o CROSS JOIN) porque el propósito y los resultados de ambas operaciones son fundamentalmente diferentes. **Diferencias entre FULL OUTER JOIN y CROSS JOIN** 1. **Condición de emparejamiento**: - En un **FULL OUTER JOIN**, se especifica una condición de emparejamiento en la cláusula ON, que indica cuáles filas deben combinarse entre las dos tablas. Se devuelven las filas que cumplen con esta condición y, adicionalmente, se incluyen todas las filas de ambas tablas que no tengan un par coincidente en la otra tabla. - En un **CROSS JOIN**, **no hay una condición de emparejamiento**. El CROSS JOIN simplemente combina cada fila de la primera tabla con **cada fila de la segunda tabla**, sin importar si tienen algún valor en común. Esto crea el producto cartesiano de las dos tablas. 2. **Resultado devuelto**: - El **FULL OUTER JOIN** devuelve un conjunto de resultados que incluye las coincidencias entre ambas tablas (basadas en la condición de emparejamiento) y también todas las filas sin coincidencias de ambas tablas, con NULL en las columnas correspondientes a la tabla sin coincidencia. - El **CROSS JOIN** devuelve un número mucho mayor de filas, ya que es la combinación de todas las filas de ambas tablas, lo que generalmente resulta en un número de filas igual a (número de filas en la primera tabla) × (número de filas en la segunda tabla). 3. **Uso de NULL**: - En un **FULL OUTER JOIN**, las filas que no tienen coincidencias en la otra tabla rellenan las columnas de la tabla opuesta con NULL. Esto permite identificar visualmente qué filas no tienen emparejamiento. - En un **CROSS JOIN**, no se usa NULL, ya que no existe un concepto de \"falta de coincidencia\"; cada fila se empareja con todas las filas de la otra tabla. ![](media/image59.png) Cross join: combina las filas de 2 tablas, no existe una condición, es decir hará una combinatoria, multiplica todas las filas y suma las columnas, cada fila se combina con cada una de las otras Las **funciones de agregación** en SQL son herramientas potentes para sintetizar y resumir datos de una o más columnas. Estas funciones procesan las filas y devuelven un único valor como resultado, aplicable a toda la tabla o en subconjuntos de filas si se utiliza el **GROUP BY**. Aquí tienes un desglose de las funciones de agregación y su uso con **GROUP BY**, seguido de ejemplos. **Tipos de funciones de agregación** 1. **COUNT**: Cuenta el número de filas en una columna, o las filas no nulas. 2. **SUM**: Suma todos los valores numéricos de una columna. 3. **AVG**: Calcula el promedio (media) de los valores en una columna. 4. **MIN**: Encuentra el valor mínimo en una columna. 5. **MAX**: Encuentra el valor máximo en una columna. ![](media/image61.png) Group by: La cláusula GROUP BY permite aplicar funciones de agregación a diferentes **grupos** de datos dentro de una tabla, en lugar de calcular una sola vez para todos los registros. Esto es útil para obtener resúmenes específicos basados en una o varias columnas de agrupamiento. En SQL, las **funciones de agregación** (como SUM, COUNT, AVG, MIN, MAX) **solo pueden aplicarse a columnas existentes en la tabla** y **no a expresiones complejas** o campos calculados que no forman parte del conjunto de datos original. Esto se debe a que estas funciones procesan datos directamente desde la base de datos, y requieren que las columnas ya existan y contengan los datos para poder realizar las operaciones de síntesis. **Restricciones de uso de funciones de agregación en agrupamientos (GROUP BY)** Cuando usas GROUP BY, hay algunas reglas importantes a tener en cuenta: 1. **Solo puedes mostrar en la consulta las columnas que están agrupadas o las que tienen una función de agregación aplicada**. Esto se debe a que GROUP BY agrupa las filas por los valores de las columnas especificadas, y como resultado, SQL no sabe qué valor específico debería mostrarse para cualquier columna no agrupada. Las funciones de agregación son una solución a esta ambigüedad, ya que sintetizan un solo valor para el grupo. En otras palabras, si tienes una columna en la selección (SELECT) que no está en GROUP BY y tampoco tiene una función de agregación, el motor de SQL no puede determinar cómo agrupar o resumir esa columna, lo que resulta en un error. 2. **Puedes aplicar funciones de agregación solo a columnas existentes**. Las funciones de agregación funcionan solo en columnas que existen en la tabla. Si necesitas usar un campo calculado o una expresión en tu consulta, debes crearlo previamente en una subconsulta o en una columna calculada. Por ejemplo, si necesitas calcular una columna como PrecioTotal = Cantidad \* PrecioUnitario, debes hacerlo primero en una subconsulta y luego aplicar una función de agregación a esa nueva columna. **Ejemplo explicativo** Imaginemos que tienes una tabla Ventas: ![](media/image63.png) **Ejemplo de uso incorrecto sin agrupación** Supón que quieres ver el PrecioUnitario sin agruparlo ni aplicarle una función de agregación. La siguiente consulta generaría un error: En este caso, SQL no sabe cómo manejar PrecioUnitario porque no está en la cláusula GROUP BY ni tiene una función de agregación. Para solucionar esto, necesitas: - Agregar PrecioUnitario a la cláusula GROUP BY, o - Aplicar una función de agregación a PrecioUnitario, como AVG(PrecioUnitario) para obtener el promedio por cada región. Ejemplo corregido con agregación o agrupamiento adecuado Si quieres ver la suma de Cantidad por región y el promedio del PrecioUnitario en cada región, tu consulta debería verse así: ![](media/image65.png) Esta consulta es válida porque Region está en GROUP BY, y Cantidad y PrecioUnitario se agrupan usando funciones de agregación (SUM y AVG, respectivamente). **Resumen** - **Las funciones de agregación solo pueden aplicarse a columnas existentes** en la tabla original o en una subconsulta. - **En consultas con GROUP BY**, solo puedes mostrar los campos de agrupamiento o los que están dentro de una función de agregación. - Si necesitas agregar un campo calculado en un GROUP BY, debes crearlo en una subconsulta o vista para que esté disponible como una \"columna existente\". Los **campos de agrupamiento** son las columnas que se especifican en la cláusula GROUP BY de una consulta SQL. Estos campos determinan cómo se agrupan las filas en subconjuntos dentro de la tabla, permitiendo que las funciones de agregación (como SUM, COUNT, AVG, etc.) operen de manera independiente sobre cada grupo. Cuando usas GROUP BY, cada valor único en los campos de agrupamiento define un grupo, y dentro de cada grupo se aplican las funciones de agregación. **Ejemplo de campos de agrupamiento** Imaginemos una tabla llamada Ventas con las siguientes columnas: Supón que quieres ver la suma de Cantidad para cada Region. Para hacerlo, puedes usar Region como campo de agrupamiento en la cláusula GROUP BY. ![](media/image67.png) **Explicación:** - En este caso, Region es el campo de agrupamiento. SQL agrupa las filas por cada valor único en la columna Region (Norte, Sur y Este). - Luego, SUM(Cantidad) se aplica a cada grupo, devolviendo un valor agregado (la suma de Cantidad) para cada Region. **Ejemplo con múltiples campos de agrupamiento** Si quieres ver el total de Cantidad por cada combinación de Region y Producto, entonces usarías ambos como campos de agrupamiento: ![](media/image69.png) **Explicación:** - Aquí, Region y Producto son los **campos de agrupamiento**. SQL agrupa las filas por cada combinación única de Region y Producto. - Luego, la función de agregación SUM(Cantidad) se aplica a cada grupo. Having: es como un where, pero para las funciones de agrupamiento es decir en where filtro lo que viene del from pero no de select o group by, para eso uso having ![](media/image71.png) Aca estoy filtrando las cantidades mayores a 4, se debe poner la operación y no el nombre que le asigno Entonces having es un filtro para las funciones de agregación que se establecieron mediante group by Orden de ejecución en SQL:\ En SQL Server, el orden de ejecución de las cláusulas en una consulta SQL es el siguiente: 1. **FROM**: Define las tablas de las que se obtendrán los datos. Si hay uniones entre tablas, estas se ejecutan en esta etapa. 2. **WHERE**: Filtra las filas antes de aplicar las agregaciones. Solo se pueden usar condiciones basadas en columnas individuales o calculadas en esta etapa, no en resultados de agregación. 3. **GROUP BY**: Agrupa las filas en subconjuntos para aplicar funciones de agregación como SUM, COUNT, AVG, etc. 4. **HAVING**: Filtra los grupos resultantes después de aplicar las funciones de agregación. Solo se pueden usar condiciones que incluyan funciones de agregación o los campos de agrupamiento definidos en GROUP BY. 5. **SELECT**: Selecciona las columnas o expresiones que se incluirán en los resultados finales. Aquí se pueden incluir las funciones de agregación y los alias de columna. 6. **ORDER BY**: Ordena los resultados finales según una o más columnas. En SQL, cuando usas **alias** (es decir, nombres nuevos) para las columnas en la cláusula SELECT, esos alias **no pueden usarse en WHERE**, ya que WHERE se ejecuta antes de SELECT en el orden de ejecución de una consulta SQL. Si intentas referenciar un alias en WHERE, obtendrás un error porque SQL aún no \"conoce\" ese alias en la etapa de WHERE. En lugar de WHERE, puedes usar el alias en las cláusulas ORDER BY y HAVING, ya que ambas se ejecutan después de SELECT. Creación de clave foránea: ![](media/image73.png) La instrucción ALTER TABLE modifica la tabla existente Employee para agregar una restricción de clave foránea llamada FK\_Employee\_Manager. Agrega **una restricción** llamada FK\_Employee\_Manager. Define **una clave foránea** (FOREIGN KEY) en la columna mgrid Hace **referencia** a la columna empid en la misma tabla Employee, indicando que mgrid debe coincidir con un empid válido de la misma tabla. CONSTRAINT se utiliza para **definir una restricción** en una tabla, es decir, una regla que los datos en la tabla deben cumplir. Las restricciones ayudan a mantener la integridad y coherencia de los datos en la base de datos. Algunos tipos de restricciones comunes incluyen: - **PRIMARY KEY**: Asegura que los valores en una columna o conjunto de columnas sean únicos y no nulos. - **FOREIGN KEY**: Garantiza que los valores en una columna (o conjunto de columnas) correspondan a valores existentes en otra tabla o en la misma tabla (autorreferencial). - **UNIQUE**: Asegura que todos los valores en una columna sean únicos. - **CHECK**: Define una condición que cada fila debe cumplir. - **NOT NULL**: Evita que se almacenen valores nulos en una columna. ejemplos de cómo se utilizan las restricciones (CONSTRAINT) en SQL para diferentes tipos de validaciones: PRIMARY KEY: En este ejemplo, PK\_Employee es una restricción de clave primaria en la columna empid, lo que garantiza que cada empid sea único en la tabla Employees. FOREIGN KEY ![](media/image75.png) FK\_Employee\_Department asegura que el valor de deptid en la tabla Employees debe coincidir con un deptid válido en la tabla Departments. UNIQUE En este ejemplo, UQ\_Email asegura que el valor en la columna email sea único en toda la tabla Users. CHECK ![](media/image77.png) CHK\_Price asegura que el valor de price sea mayor que 0, y CHK\_Stock asegura que stock sea igual o mayor que 0. Formas de definir la clave primaria: 1. **Definición directa en la columna**: Cuando defines PRIMARY KEY inmediatamente después del tipo de dato de la columna (como en orderid INT PRIMARY KEY), SQL entiende automáticamente que es una restricción de clave primaria, sin necesidad de agregar explícitamente el nombre de la restricción con CONSTRAINT. 2. **Definición con CONSTRAINT**: Alternativamente, puedes definir la clave primaria al final de la declaración de la tabla usando CONSTRAINT para darle un nombre específico a la restricción. Esto es útil si quieres nombrar la restricción para hacer referencia a ella fácilmente en el futuro (por ejemplo, si necesitas eliminarla). Paréntesis en los Or: ![](media/image80.png) Los paréntesis se utilizan en esta consulta SQL para **agrupar las condiciones de la cláusula OR**. Esto asegura que las condiciones OR se evalúen juntas como un solo grupo en la cláusula WHERE, en lugar de evaluarse individualmente o en combinación con la condición anterior de AND Si no se usaran paréntesis, SQL podría interpretar que solo algunas de las condiciones de OR están relacionadas con la cláusula AND, lo cual alteraría el resultado de la consulta. Case: l CASE en SQL es una **expresión escalar**, lo que significa que **siempre devuelve un valor único o NULL** como resultado. A diferencia de una estructura de control como SWITCH en lenguajes de programación, el CASE no \"controla\" el flujo de ejecución, sino que simplemente **evalúa condiciones** y devuelve el resultado de la primera condición que sea verdadera. Esto lo convierte en una herramienta muy versátil para realizar cálculos condicionales dentro de consultas SQL. puede usarse en \"cualquier lugar donde se permita una expresión\", significa que puedes utilizarlo en cualquier parte de una consulta SQL donde el sistema permita usar un valor o cálculo como parte de la lógica Usos comunes: Dentro de un SELECT (para calcular valores condicionales). En el WHERE (aunque indirectamente, dentro de subconsultas). En la cláusula ORDER BY (para ordenar condicionalmente). En la cláusula GROUP BY (campo calculado dentro del SELECT y agrupar por ese resultado.). Ejemplos: **1) Forma sencilla (CASE simple)**: Evalúa un valor contra múltiples opciones. 2\) **Forma con condiciones (CASE buscado)**: Evalúa expresiones booleanas ![](media/image82.png) 3\) Dentro de los WHEN, puedes realizar múltiples tipos de comparaciones y combinar condiciones usando operadores como AND o OR. Subconsultas: en SQL son consultas anidadas dentro de otra consulta. Sirven para realizar tareas complejas dividiéndolas en pasos más pequeños y lógicos. Aunque son muy útiles, **pueden afectar el rendimiento** si no se diseñan correctamente, especialmente cuando son muy complejas o tienen dependencias. ![](media/image84.png) Se clasifican de acuerdo a: - Dependencias: - Autocontenidas: Estas subconsultas no dependen de la consulta externa para ejecutarse. Pueden ejecutarse de forma independiente. - Correlacionadas: Estas subconsultas dependen de la consulta externa porque hacen referencia a columnas de la consulta principal. Se ejecutan para cada fila de la consulta externa, se las puede realizar en SELECT, WHERE y HAVING - Por cantidad de valores: - Escalar: Devuelve un solo valor (una fila con una sola columna). Se puede usar en cualquier lugar donde sea necesario un valor escalar. - Multivaluada: devuelve una lista que es una tabla de una sola columna o tubular en la que puede devolver una tabla compuesta o parte de una tabla, cuando es multivaluada utilizo IN, ANY O ALL de comparador, las subconsultas tubulares solo se pueden hacer en el from - Aplicables a: - Select, from, where y having - Insert, update y delete Subconsulta autocontenida multivaluada: **Consulta:** Obtener los nombres de los empleados que trabajan en departamentos ubicados en la ciudad de \"New York\". Esta subconsulta es autocontenida porque puede ejecutarse de forma independiente sin depender de la consulta externa. Devuelve una lista de IDs (department\_id) de todos los departamentos en \"New York\". El resultado es **multivaluado** porque puede devolver múltiples valores en una sola columna. La **consulta externa**: Utiliza la subconsulta en la cláusula WHERE para filtrar empleados cuyos department\_id coincidan con los resultados devueltos por la subconsulta. La subconsulta se ejecuta **primero** y devuelve una lista de department\_id donde la ubicación es \"New York\". Luego, la consulta externa utiliza esa lista para comparar y filtrar empleados. En este caso, el operador IN asegura que solo se seleccionen los empleados cuyo department\_id coincida con uno de los valores de esa lista. Autocontenida tubular multivaluada: **Es autocontenida**, lo que significa que **no depende** de la consulta externa. Devuelve **múltiples valores** (una tabla con varias columnas y varias filas). Se utiliza en la cláusula **FROM**, y se conoce como una **tabla derivada**. Calcula cuántos clientes distintos (CustomerID) hicieron pedidos en cada año ![](media/image86.png) Subconsulta: Obtiene el año (YEAR(orderdate)) de la fecha del pedido (orderdate) y el CustomerID (ID del cliente) desde la tabla SalesLT.SalesOrderHeader. Asigna un alias orderyear a la columna del año del pedido Consulta Externa: Agrupa los datos por año del pedido (orderyear). Cuenta cuántos clientes distintos (COUNT(DISTINCT CustomerID)) hicieron pedidos en cada año. Asigna el alias numcusts a esta cantidad. Correlacionada en select: Queremos listar el nombre de cada empleado, su salario, el nombre de su departamento y el **salario promedio** de todos los empleados en ese departamento. La consulta principal selecciona los datos del empleado (e.name, e.salary) y su departamento (d.department\_name). Utilizamos un **JOIN** para conectar la tabla employees con la tabla departments usando department\_id. La subconsulta correlacionada calcula el salario promedio de todos los empleados que están en el mismo departamento que el empleado actual (e.department\_id). Usa una segunda referencia a la tabla employees (alias e2) para comparar los department\_id y calcular el promedio. La consulta externa recorre este \"array de filas\" una por una. Para cada fila de la consulta externa, la subconsulta se ejecuta como una operación específica relacionada con esa fila. 1 itera sobre cada fila de la tabla employees (alias e). 2 para cada fila (empleado), ejecuta la subconsulta: - Filtra todas las filas de employees (alias e2) donde e2.department\_id coincida con el department\_id de la fila actual (e.department\_id). - Calcula el promedio de los salarios de las filas filtradas. 3 devuelve los resultados, incluyendo el nombre, salario, y el promedio calculado. Subconsultas con ALL, SOME o ANY: Permite usar comparadores escalares (\ 2. **DELETED** - Contiene los valores **anteriores** de las filas afectadas por la operación: - En un **DELETE**, contiene las filas eliminadas. - En un **UPDATE**, contiene las filas antes de la actualización. - Útil para auditar o realizar validaciones previas Ejemplo ![](media/image98.png) ### **Uso de las Tablas Especiales en Triggers INSTEAD OF** Cuando el trigger es del tipo INSTEAD OF, ambas tablas (INSERTED y DELETED) pueden estar disponibles simultáneamente, ya que este tipo de trigger intercepta el evento antes de que ocurra y puede modificar el flujo de la operación. - En un **UPDATE**, por ejemplo: - La tabla INSERTED contiene los valores **nuevos**. - La tabla DELETED contiene los valores **anteriores**. **Ejemplo: Trigger INSTEAD OF con ambas tablas** ### Consideraciones al Usar Triggers - **Rendimiento**: Los triggers pueden afectar el rendimiento si realizan operaciones costosas o si se ejecutan con frecuencia. - **Complejidad**: Pueden hacer que la lógica de la base de datos sea más compleja y difícil de seguir. - **Depuración**: Al ser automáticos, pueden dificultar la depuración si ocurren errores o comportamientos inesperados. ### Funcionamiento de los Triggers - -