lunes, 30 de mayo de 2016

Funciones de Grupo.

Objetivos: 
•Identificar las funciones de grupo disponibles.
•Describir el uso de las funciones de grupo.
•Agrupar datos mediante la cláusula GROUP BY.
•Incluir o excluir filas agrupadas utilizando la cláusula HAVING.

NOTA: Usamos como ejemplo la base de datos: ORCL, la cual viene por defecto en cualquier versión de ORACLE.
_____________________________________________________________________________________
Funciones de Grupo.
A diferencia de las funciones de una sola fila, las funciones de grupo operan en juegos de filas para dar un resultado por grupo. Estos juegos pueden abarcar toda la tabla o la tabla dividida en grupos.

Sintaxis
SELECT [ column, group_function( [DISTINCTcolumn)
FROM table
[WHERE condition]
[GROUP BY group_by_expression]
[HAVING group_condition]
[ORDER BY column];
Descripción:
A diferencia de las funciones de una sola fila, las funciones de grupo operan en juegos de filas para dar un resultado por grupo. Estos juegos pueden abarcar toda la tabla o la tabla dividida en grupos.
•Todas las funciones de grupo ignoran los valores nulos de la columna, pero con el uso de las funciones NVL/NVL2/COALESCE puedes forzar a las funciones de grupo a incluir valores nulos.
•Utilice la palabra clave DISTINCT column  para suprimir el recuento de valores duplicados en una columna.
•En la Sintaxis GROUP BY es usado para dividir las filas de una tabla en grupos, group_by_expression especifica columnas cuyos valores determinan la base para agrupar filas. 
•Utilize HAVING para restringir los grupos a mostrar. HAVING es equivalente a WHERE, con la diferencia que HAVING es para restringir grupos, mientras que WHERE restringe filas de datos. group_condition es la condición de restricción aplicada a los grupos.
_____________________________________________________________________________________
Algunas Funciones de Grupo.
Cada una de las funciones acepta un argumento. A continuación mostramos el uso de algunas de ellas: 
AVG([DISTINCT | ALL] expr): Retorna el valor medio o promedio de expr. Omite los valores nulos.
COUNT({ * | [DISTINCT | ALL] expr}): Retorna el Número de filas, en las que expr se evalúa como algo no nulo ( si se usa * cuenta todas las filas de la tabla, incluidas las duplicadas y las que contienen valores nulos).
MAX([DISTINCT | ALL] expr): Retorna el Valor máximo de expr; se ignoran los valores nulos.
MIN([DISTINCT ALL] expr): Retorna el Valor mínimo de expr; se ignoran los valores nulos.
STDDEV([DISTINCT | ALLexpr):Retorna la Desviación estándar de expr; se ignoran los valores nulos.
SUM([DISTINCT | ALLexpr): Retorna la sumatoria total de expr. se omiten los valores nulos.

VARIANCE([DISTINCT | ALLexpr): Retorna la varianza o cuadrado de la desviación estándar de expr. Omite los valores nulos.

Otros Complementos.
DISTINCT hace que la función considere únicamente valores no duplicados; ALL hace que considere todos los valores, incluidos los duplicados. El valor por defecto es ALL y, por tanto, no es necesario especificarlo. 
•Los tipos de datos para las funciones con un argumento expr pueden ser CHAR, VARCHAR2, NUMBER o DATE
•Todas las funciones de grupo ignoran los valores nulos. Para sustituir con un valor los valores nulos, utilice las funciones NVL, NVL2 o COALESCE.
Al usar GROUP BY, Es posible agrupar por mas de una Columna.
•Al igual que las funciones de fila única, es posible anidar las funciones de Grupo.
_____________________________________________________________________________________
Uso de las Funciones de Grupo.
El Fin de estas funciones es el de obtener información de resumen (como por ejemplo, medias, cantidad, etc...) para grupos de filas.

Ejemplos:
SELECT 
        COUNT(salary), MAX(salary),
       MIN(salary), SUM(salary),
       AVG(salary), STDDEV(salary),
       VARIANCE(salary)
FROM hr.employees;
/*En el ejemplo anterior aplicamos las funciones de grupo ya explicadas al campo salary de la tabla employees*/
---
SELECT 
      COUNT(DISTINCT salary), COUNT(salary),
      AVG(NVL(COMMISSION_PCT,0)),AVG(COMMISSION_PCT),
      MIN(last_name), MAX(last_name)
FROM hr.employees;
/*En el anterior ejemplo vemos el uso de DISTINCT y la función NVL en conjunto con las funciones de grupo, la 1ra columna muestra la cantidad de salarios distintos en toda la tabla; la 2da muestra la cantidad de empleados con salarios; la 3ra muestra el promedio de COMMISSION_PCT tomando en cuenta la cantidad de empleados total, la 4ta muestra el promedio tomando en cuenta solo los empleados que ganan comisión; la 5ta muestra el uso de la función MIN con campos tipo carácter y la 6ta el uso de MAX también en campos tipo carácter.*/
---
SELECT 
      COUNT(*), COUNT(COMMISSION_PCT),
      MIN(hire_date), MAX(hire_date)

FROM employees;
/*En el Query anterior en la columna 1 se usa la función de grupo COUNT(*), para determinar la cantidad total de registros de la tabla Employees; columna 2 muestra la cantidad de empleados con Comisión Salariar; la 3ra columna muestra la fecha de contratación del empleado mas viejo de la empresa; la 4ra muestra la fecha de contratación del empleado mas reciente de la empresa.*/
---
SELECT department_id AS "Departamento", 
       COUNT(*) AS "Cantidad Empleado",
       MIN(salary) AS "Salario Mínimo",
       AVG(salary) AS "Salario Promedio",
       MAX(salary) AS "Salario Máximo"
FROM employees 
GROUP BY department_id
ORDER BY 2 desc;
/*En el Query anterior la 1ra columna muestra el numero de departamento; la 2da muestra la cantidad de empleados de ese departamento; la 3ra muestra el salario mínimo de ese departamento; la 4ta muestra el salario promedio y la 5ta muestra el salario máximo.

Nota: La columna(department_id) en la cláusula GROUP BY no tiene que estar necesariamente en la cláusula SELECT. Sin embargo, sin los números de departamento, los resultados no parecen significativos. */
---
Grupos Dentro de Grupos.
En ocasiones, necesita ver los resultados para grupos dentro de grupos. A continuación se muestra un informe que detalla el salario total que se paga a cada cargo en cada departamento. 

SELECT department_id dept_id, job_id, SUM(salary)
FROM employees
GROUP BY department_id, job_id;
/*La tabla EMPLOYEES se agrupa primero por número de departamento y después por cargo dentro de esa agrupación. Por ejemplo, los cuatro administrativos del departamento 50 se agrupan juntos y se crea un único resultado (salario total) para todos los administrativos del grupo.*/
---
•La cláusula GROUP BY especifica cómo se deben agrupar las filas: 
-En primer lugar, las filas se agrupan por número de departamento. 
-En segundo lugar, las filas se agrupan por identificador de trabajo de los grupos de número de departamento. 

Así pues, la función SUM se aplica a la columna de salarios para todos los identificadores de trabajo de cada grupo de números de departamento.

Restricción de resultados de Grupos.
De la misma forma que utiliza la cláusula WHERE para restringir las filas que se seleccionarán, utilice la cláusula HAVING para restringir grupos. Para buscar el salario máximo de cada departamento que tenga un salario máximo superior a 10.000 dólares, necesita: 
1. Buscar el salario máximo de cada departamento agrupando por número de departamento. 
2. Restringir los grupos a los departamentos con un salario máximo superior a 10.000 dólares.

Ejemplo:
SELECT job_id, SUM(salary)  AS NÓMINA
FROM employees
WHERE job_id NOT LIKE '%REP%'
GROUP BY job_id
HAVING SUM(salary) > 13000
ORDER BY SUM(salary);
/*El ejemplo anterior muestra el identificador de trabajo y el salario mensual total de cada trabajo que tiene una nómina total superior a 13000. El ejemplo excluye a los representantes de venta y ordena la lista por salario mensual total.*/
---
Anidando Funciones de Grupo.
Las funciones de grupo se pueden anidar hasta una profundidad de dos. El ejemplo a continuación muestra el salario medio máximo.

SELECT MAX(AVG(salary))
FROM employees
GROUP BY department_id ;
_____________________________________________________________________________________
_____________________________________________________________________________________
Fuente: Base de Datos Oracle 10g: Conceptos Fundamentales de SQL 1

sábado, 21 de mayo de 2016

Funciones de Conversión-(Funciones de una Fila SQL, Parte 3)

Objetivos: 
•Describir las Conversiones Implícitas y Explicitas de SQL.
•Describir el uso de las funciones de conversión.
•Describir el uso de las funciones generales de SQL ORACLE.
•Describir las Expresiones Condicionales.
NOTA: Usamos como ejemplo la base de datos: ORCL, la cual viene por defecto en cualquier versión de ORACLE.
_____________________________________________________________________________________
Funciones de Conversion.
Las funciones de conversión convierten un valor de un tipo de dato a otro. Ahora bien ORACLE SERVER tiene un mecanismo interno de conversion implícita el cual funciona así:

Conversiones Implícitas:
•Si X columna, variable, función, etc espera un tipo de dato y recibe otro diferente, ORACLE SERVER lo convierte implícitamente siempre y cuando sea posible. La siguiente tabla muestra las conversiones implícitas posibles:
De A
VARCHAR2 o CHAR NUMBER
VARCHAR2 CHAR DATE
NUMBER VARCHAR2 
DATE VARCHAR2 
•Repito, ORACLE SERVER hace dichas conversiones siempre y cuando sea posible, osea, la conversion de VARCHAR2 NUMBER es posible si la cadena de caracteres representa un número válido. Eje: salary = '12000'De igual manera la Conversion de VARCHAR2 a  DATE es posible si la cadena de caracteres representa una fecha valida. Eje: hire_date = '12-jun-06'. El caso de la conversiones de NUMBER DATE VARCHAR2 son siempre posibles ya que cualquier cadena de caracteres puede ser VARCHAR2 : '695*/,.%32@'.
_____________________________________________________________________________________
Conversiones Explicitas.
•Como no siempre las conversiones Implícitas son posibles y también cuando se da la necesidad de convertir los datos con un formato especifico es requerido utilizar las Funciones de Conversion disponibles en ORACLE SQL.
---
Función: TO_CHAR.
SintaxisTO_CHAR(number|date,[ fmt], [nlsparams])
Descripción: Convierte un valor numérico o de fecha a una cadena de caracteres VARCHAR2 con el modelo de formato fmt(opcional)Conversión de fecha: El parámetro nlsparams(opcional) especifica el lenguaje en que se devolverán los nombres y las abreviaturas de mes y día, Si se omite este parámetro, esta función utiliza los lenguajes de fecha por defecto para la sesión. Conversión numérica: El parámetro nlsparams especifica los siguientes caracteres, que son devueltos por elementos de formato numérico:
•Carácter decimal
•Separador de grupos
•Símbolo de divisa local
•Símbolo de divisa internacional, Si se omite nlsparams o cualquier otro parámetro, esta función utiliza los valores de parámetros por defecto para la sesión.
---
Función: TO_NUMBER.
Sintaxis: TO_NUMBER(char,[fmt], [nlsparams])

Descripción:  Convierte una cadena de caracteres que contenga dígitos en un número con el formato especificado por el modelo de formato opcional fmt. El parámetro nlsparams tiene el mismo objetivo en esta función que en la función TO_CHAR de conversión numérica.
---
Función: TO_DATE.
Sintaxis: TO_DATE(char,[fmt], [nlsparams])

Descripción: Convierte una cadena de caracteres que representa una fecha en un valor de fecha de acuerdo con el fmtque se haya especificado. Si se omite fmt, el formato es DD-MON-YY. El parámetro nlsparams tiene el mismo objetivo en esta función que en la función TO_CHAR de conversión de fecha.
Nota: Las funciones mencionadas anteriormente únicamente suponen una parte de las funciones de conversión disponibles. Para una mayor lista consulte “Conversion Functions” en Oracle SQL Reference.
_____________________________________________________________________________________
Uso Función TO_CHAR.

Uso de TO_CHAR con fechas.

Esta función es ideal para mostrar la fecha en un formato diferente al definido por defecto en la Base de Datos.
•El modelo de formato debe ir entre comillas simples y es sensible a mayúsculas/minúsculas.
•El modelo de formato puede incluir cualquier elemento de formato de fecha. Asegúrese de separar el valor de fecha del modelo de formato con una coma.
•Los nombres de días y meses de la salida se rellenan automáticamente con espacios en blanco.
•Para eliminar espacios en blanco rellenados o para suprimir ceros iniciales, utilice el elemento fm del modo de relleno.

Algunos elementos útiles para el formato de Fechas.
Elemento Resultado
YYYY Año completo con números
YEAR Nombre completo del año con letras (en inglés)
MM Valor de dos dígitos para el mes
MONTH Nombre completo del mes
MON Abreviatura de tres letras del mes
DY Abreviatura de tres letras del día de la semana
DAY Nombre completo del día de la semana
DD Día del mes con números
TH Número ordinal (por ejemplo, DDTH para 11TH)
SP Número completo con letras (por ejemplo, DDSP para EIGHT
SPTH o THSP Número ordinal completo con letras (por ejemplo, DDSPTH para FIFTEENTH
AM o PM Indicador de meridiano
A.M. o P.M.. Indicador de meridiano, con puntos
HH o HH12 o HH24 Hora del día, u hora (112) u hora (023)
/  .  ,   La puntuación se reproduce en el resultado.
“de” Lo que esta dentro de las comillas se reproduce en el resultado.
Ejemplos:
SELECT 
    TO_CHAR(SYSDATE,'fmDay, Month DD "of" YYYY') "Fecha en Ingles con fm",
    TO_CHAR(SYSDATE,'DAY, MONTH DD "of" YYYY') "Fecha en Ingles sin fm",
    TO_CHAR(SYSDATE+4,'DY, DD/MON/YY') "Fecha+4 Abreviada",
    TO_CHAR(SYSDATE,'Month.YYYY') ". Mes y Año sin fm",
    TO_CHAR(SYSDATE,'fmDay dd "de" Month','NLS_DATE_LANGUAGE=SPANISH') "Dia y Mes en Español"
FROM DUAL;
/*En el Query anterior la primera columna muestra el Día y Mes en letras, el literal "of" y el año en dígitos, algunos espacios son removidos con fm; La 2da columna muestra lo mismo pero sin fm; En la 3ra columna se le suma 4  días a la fecha y se muestra abreviada; La 4ta columna muestra solo el Mes y Año sin fm y la ultima muestra el Día y Mes en Español con fm. Como Nota: nlsparams fmt son opcionales*/
---
SELECT 
    TO_CHAR(SYSDATE,'FMDAY DDth') "Ejemplo con TH",
    TO_CHAR(SYSDATE,'Day Ddthsp') "Ejemplos con THSP",
    TO_CHAR(SYSDATE,'HH12:MI:SS:SSSS PM') "Hora HH12, SSSS y Meriado ",
    TO_CHAR(SYSDATE,'HH24:MI:SS AM') "Hora HH24, Meriano y sin SSSS"
FROM DUAL;
/*El Query anterior muestra el Día actual y su equivalente en numero ordinal abreviado(Col 1); El Día y su equivalente ordinal en letras(Col 2); La hora en formato 12 horas, minutos, segundos,  milésimas de segundos y el meridiano (Col 3); La hora en formato 24 horas, minutos, segundos y meridiano.*/
---
Uso de TO_CHAR con Números.
Existen escenarios en los cuales es requerido dar un formato X a una cifra numérica, en esos casos nos valemos de la función TO_CHAR para así lograr el cometido. 

Es bueno tener en cuenta que:
•Oracle Server muestra una cadena de signos numéricos (#) en lugar de un número completo cuyos dígitos excedan el número de dígitos que se proporciona en el modelo de formato.
•Oracle Server redondea el valor decimal almacenado al número de posiciones decimales que se proporciona en el modelo de formato.

Algunos elementos útiles para el formato de Números.
Elemento Resultado
9 Representa un número
0 Muestra ceros
$ Coloca un signo de dólar flotante
L Utiliza el símbolo de divisa local flotante
. Imprime un punto decimal
, Imprime una coma como indicador de miles
Ejemplo:
SELECT
    TO_CHAR(19999999.99,'fm$9,999,999.00') AS "Muestra #",
    TO_CHAR(1999999.99,'fm$9,999,999.00'AS "Muestra Cifra",
    TO_CHAR(199999.9,'fm$9,999,999.00'AS "Muestra Cifra 2",
    TO_CHAR(19999.999,'fm$9,999,999.00'AS "Redondea",
    TO_CHAR(199.333,'fm$9,999,999.00'AS "Redondea 2"
FROM DUAL;
/*En la anterior consulta usamos el mismo formato con diferentes cantidades para así poder apreciar como funciona el TO_CHAR  con números, la primera cifra tiene un dígito entero mas que el modelo de formato, por lo cual el resultado es una cadena de '#'; la 2da cifra es mostrada como se espera con las comas y punto en el lugar esperado; en la 3ra todo sale bien como en la 2ra; en la 4ta la cifra tiene un decimal mas que el propuesto en el modelo de formato, por lo cual dicha cifra es redondeada; en la ultima también la cifra es redondeada.*/
_____________________________________________________________________________________
Uso Funciones TO_NUMBER y TO_DATE.

De la function TO_NUMBER no hay mucho que decir, ella transforma una cadena de carácter que de alguna manera representa una cifra numérica a números simples, uno de sus usos mas comunes es el de validar si un campo o expresión contiene dígitos. Es mas común el uso de TO_DATE, la cual nos ayuda a dar formato a una cadena de carácter que tiene un formato de fecha diferente al que tenemos en la Base de Datos o diferente al que queremos mostrar.

Sintaxis
TO_NUMBER(char[, 'format_model'])
TO_DATE(char[, 'format_model'])

Descripción: El modificador fx especifica la correspondencia exacta del argumento de carácter y el modelo de formato de fecha de una función TO_DATE.
•La puntuación y el texto entre comillas del argumento de carácter debe corresponder exactamente (excepto en las mayúsculas/minúsculas) con las partes correspondientes del modelo de formato.
•El argumento de carácter no puede contener espacios en blanco adicionales. Sin fx, Oracle ignora los espacios en blanco adicionales.
•Los datos numéricos del argumento de carácter debe tener el mismo número de dígitos que el elemento correspondiente del modelo de formato. Sin fx, los números del argumento de carácter pueden omitir los ceros iniciales.
Ejemplos:
SELECT
     TO_NUMBER('$1,845.5','$999,999,999.00') "TO_NUMBER",
     TO_NUMBER('$741,881,845','$999,999,999.00') "TO_NUMBER",
     TO_NUMBER('$41,845.99','$999,999,999.00') "TO_NUMBER"
FROM DUAL;
/*Supongamos que tengamos algunas cantidades numéricas con un formato X en forma de string y debamos almacenar dichas cifras en la base de datos pero en su forma numérica, el query anterior muestra el uso de TO_NUMBER.*/
---
SELECT 
    TO_DATE('2017-18-08','YYYY-DD-MM') AS "FECHA 1",
    TO_DATE('17.1.2018','DD.MM.YYYY'AS "FECHA 2",
    TO_DATE('MAY 17, 2014','MONTH DD, YYYY'AS "FECHA 3",
    TO_DATE('2,JUNE,2019','DD,MONTH,YYYY'AS "FECHA 4"
FROM   DUAL;
/*Como Apreciamos en el ejemplo anterior, TO_DATE toma una cadena de caracteres con un formato de fecha valido pero diferente al de la Base de Datos y la adecua a ella.*/
_____________________________________________________________________________________
Anidando Funciones.

La Técnica de anidar funciones es Vital en en desarrollo y mantenimiento de procesos en una Base de Datos, esto nos permite obtener resultados claves en diferentes consultas comunes del día a día, por ello es necesario tener claro su uso y tratar de familiarizarse lo mas que podamos con ella.

Como Funciona esta técnica:
•Las funciones anidadas se evalúan desde el nivel más interno al más externo.
•Las funciones de una sola fila se pueden anidar hasta cualquier profundidad.
Ejemplo:
SELECT LAST_NAME, JOB_ID,
       UPPER(CONCAT(SUBSTR (LAST_NAME, 1, 3), SUBSTR(JOB_ID,INSTR(JOB_ID,'_'),5))),
       LENGTH(UPPER(CONCAT(SUBSTR (LAST_NAME, 13), SUBSTR(JOB_ID,INSTR(JOB_ID,'_'),5))))
FROM employees;
/*En el ejemplo anterior mostramos el nombre(LAST_NAME) y puesto(JOB_ID) de cada empleado, luego en la 3ra columna determinamos(INSTR ) la posición inicial del carácter '_' en la cadena JOB_ID y a partir de esa posición retornamos(SUBSTR) 5 caracteres del mismo JOB_ID, eso es concatenado(CONCAT) con los tres primeros caracteres del nombre y por último todo esto es convertido(UPPER) a letras MAYÚSCULAS, en la 4ta columna se muestra la cantidad(LENGTH) de caracteres que tiene la 3ra columna.*/
_____________________________________________________________________________________
Algunas Funciones Generales.

Estas funciones pueden utilizar cualquier tipo de datos y están relacionadas con el uso de valores nulos: 

Función NVL.
Sintaxis
NVL(expr1, expr2)
Descripción:
•Convierte un valor nulo en un valor real.
•Los parámetros pueden ser de cualquier tipo de dato pero deben corresponder entre ellos, entiéndase que ambos deben ser del mismo tipo.
expr1 es el valor o la expresión de origen que puede contener un valor nulo.
expr2 es el valor de retorno si expr1 es nulo.
•Como retorna uno de los parámetros, el valor retornado es del mismo tipo que ellos.
Ejemplo:
SELECT EMPLOYEE_ID AS COL1 ,
    NVL(MANAGER_ID,0AS COL2,
    NVL(TO_CHAR(COMMISSION_PCT),'No Comision'AS COL3,
    NVL(HIRE_DATE,SYSDATE) AS COL4
FROM HR.EMPLOYEES
WHERE EMPLOYEE_ID IN (204,145,100);
/*El anterior ejemplo muestra el código de empleado(COL1 ) , el código de su manager(COL2) y si no tiene manager muestra 0 como es el caso del emp#: 100, la comisión(COL3) que gana y si no tiene muestra 'No Comisión'(la comisión fue convertida a CHAR para satisfacer la Función NVL) y finalmente se muestra la fecha de contratación(COL4) de los empleado 204,145 y 100.*/
--
Función NVL2.
Sintaxis
NVL2(expr1, expr2, expr3)
Descripción:
•La función NVL2 examina la primera expresión. Si la primera expresión no es nula, la función NVL2 devuelve la segunda expresión. Si la primera expresión es nula, se devuelve la tercera expresión.
expr1 es el valor o la expresión de origen que puede contener un valor nulo.
expr2 es el valor que se devuelve si expr1 no es nulo.
expr3 es el valor que se devuelve si expr2 es nulo.
Nota: El argumento expr1 puede tener cualquier tipo de datos. Los argumentos expr2 y expr3 pueden tener cualquier tipo de datos excepto LONG. Si los tipos de datos de expr2 y expr3 son diferentes, Oracle Server convierte expr3 al tipo de datos de expr2 antes de compararlos a menos que expr3 sea una constante nula. En el último caso, no es necesaria una conversión del tipo de datos. El tipo de datos del valor de retorno es siempre el mismo que el tipo de datos de expr2, a menos que expr2 sean datos de carácter, en cuyo caso el tipo de datos del valor de retorno es VARCHAR2.
Ejemplo:
SELECT last_name, salary, commission_pct,
         NVL2(commission_pct, 'SAL+COMM', 'SAL') income
FROM employees 
WHERE department_id IN (50, 80);
/*En el pasado ejemplo mostramos el nombre salario y comisión de los empleados de los departamentos 50 y 80, para los empleados que ganan comisión la 4ta columna mostrara: 'SAL+COMM' y para los que no mostrara: 'SAL.'*/
---
Función NULLIF.
Sintaxis
NULLIF (expr1, expr2)
Descripción
•La función NULLIF compara dos expresiones. Si son iguales, la función devuelve un valor nulo. Si diferentes, la función devuelve la primera expresión. 
expr1 es el valor de origen que se compara con expr2.
expr2 es el valor de origen que se compara con expr1 (Si no es igual que expr1, se devuelve expr1.).
•No puede especificar el literal NULL para la primera expresión(expr1 ).
Ejemplo:
SELECT 
    first_name, LENGTH(first_name) "expr1", 
    last_name, LENGTH(last_name) "expr2",
    NULLIF(LENGTH(first_name), LENGTH(last_name)) result 
FROM hr.employees;
/*En el ejemplo anterior se muestra el nombre seguido de la cantidad de caracteres que lo compone, luego se hace lo mismo con el apellido y por último se evalúan(NULLIF) los tamaños de ambas cadenas, los empleados con la misma cantidad de caracteres en el nombre y apellido muestran null, en los que no, se muestra el tamaño del nombre.*/
---
Función COALESCE.
Sintaxis
COALESCE (expr1, expr2, ... exprn)
Descripción
•Si la primera expresión no es nula, la función COALESCE devuelve esa expresión; en caso contrario, realiza una fusión (COALESCE) de las expresiones restantes.
expr1 devuelve esta expresión si no es nula.
expr2 devuelve esta expresión si la primera expresión es nula y esta expresión no lo es.
exprn devuelve esta expresión si las expresiones precedentes son nulas.
•Todas las expresiones deben ser del mismo tipo de datos.
•Si todos los parámetros son Nulos, la función retorna NULL.
Ejemplo
SELECT commission_pct, manager_id,
       COALESCE(commission_pct, manager_id, -1) comm
FROM hr.employees
ORDER BY manager_id DESC, commission_pct DESC;
/*En el ejemplo anterior, si el valor COMMISSION_PCT no es nulo, se muestra en la ultima columna(comm). Si el valor COMMISSION_PCT es nulo, se muestra MANAGER_ID. Si los valores MANAGER_ID y COMMISSION_PCT son nulos, se muestra el valor –1.*/
_____________________________________________________________________________________
Expresiones Condicionales.

•Permiten utilizar la lógica IF-THEN-ELSE dentro de una sentencia SQL
•Los dos métodos utilizados para implementar procesamiento condicional (lógica IF-THEN-ELSE) en una sentencia SQL son la expresión CASE y la función DECODE
Nota: La expresión CASE cumple con ANSI SQL. La función DECODE es específica de la sintaxis Oracle.

Expresión Case.
Sintaxis
---CASE simple.
CASE expr WHEN comparison_expr1 THEN return_expr1
                  [WHEN comparison_expr2 THEN return_expr2
                    WHEN comparison_exprn THEN return_exprn
                    ELSE else_expr]
END
---CASE buscada.
CASE WHEN expr  '!' comparison_expr1 THEN return_expr1
          [WHEN expr  '!' comparison_expr2 THEN return_expr2
           WHEN expr  '!' comparison_exprn THEN return_exprn
           ELSE else_expr]
END
Descripción:
'!' Entiéndase como un operador de comparación cualquiera.
•Las expresiones CASE le permiten utilizar la lógica IF-THEN-ELSE en sentencias SQL sin llamar a procedimientos. 
•En una expresión CASE simple, Oracle Server busca el primer par WHEN ... THEN en el que expr sea igual a comparison_expr y devuelve return_expr. Si ninguno de los pares WHEN ... THEN cumplen esta condición y si existe una cláusula ELSE, Oracle Server devuelve else_expr. De lo contrario, Oracle Server devuelve un valor nulo. No puede especificar el literal NULL para todas las expresiones return_exprs y else_expr
•En una expresión CASE buscada, la búsqueda se produce de izquierda a derecha hasta que se encuentre una incidencia de la condición mostrada y, entonces, devuelve la expresión de retorno. Si no se encuentra ninguna condición que sea verdadera y si existe una cláusula ELSE, se devuelve la expresión de retorno de la cláusula ELSE; de lo contrario, devuelve NULL.
•Todas las expresiones ( expr, comparison_expr y return_expr) deben ser del mismo tipo de datos, que puede ser CHAR, VARCHAR2, NCHAR o NVARCHAR2.
Ejemplos.
SELECT last_name, job_id, salary,
       CASE job_id WHEN 'IT_PROG'  THEN  1.10*salary 
                              WHEN 'ST_CLERK' THEN  1.15*salary 
                              WHEN 'SA_REP'   THEN  1.20*salary 
                              ELSE salary 
        END   AS  "REVISED SALARY" 
FROM hr.employees; 
/*En el Query anterior se evalúa el puesto de trabajo(job_id ) de cada empleado. Si es 'IT_PROG', se le suma 10% al salario; si es 'ST_CLERK', se le suma 15%; si es 'SA_REP', se le suma 20%. Finalmente si no es ninguno se ellos se mantiene el mismo salario.*/
---
SELECT last_name,salary,
  (CASE WHEN salary<5000 THEN 'Salario Bajo'
               WHEN salary<10000 THEN 'Salario Regular'
               WHEN salary<20000 THEN 'Buen Salario'
                ELSE 'This guy is Rich'
END) AS "Calidad Salario"
FROM hr.employees;
/*En el Query anterior se evalúa el salario de cada empleado. Si es menor que 5000, nuestra columna "Calidad Salario" muestra: 'Salario Bajo'; si es menor que 10000 muestra: 'Salario Regular'; si es menor que 20000, muestra:  'Buen Salario'. Si no cumple ninguna de las condiciones anteriores muestra: 'This guy is Rich'*./
--
Función Decode.
Sintaxis
DECODE(col|expression, search1, result1 
        [, search2, result2,...,]
        [, default])
Descripción:
•La función DECODE descodifica una expresión de forma parecida a la lógica IF-THEN-ELSE o CASE que se utilizan en varios lenguajes.
•La función DECODE descodifica la expression tras compararla con cada valor search. Si la expresión es igual que search, se devuelve result.
•Si se omite el valor por defecto(default), se devuelve un valor nulo donde un valor de búsqueda no corresponda a ninguno de los valores del resultado.
Ejemplos.
SELECT last_name, job_id, salary,
       DECODE(job_id, 'IT_PROG',  1.10*salary, 
                                      'ST_CLERK', 1.15*salary, 
                                      'SA_REP',   1.20*salary, 
                                       salary) AS "REVISED SALARY" 
FROM hr.employees; 
/*Este ejemplo es el mismo primer ejemplo de la Expresión CASE, pero ahora con DECODE.*/
---
SELECT last_name, salary, TRUNC(salary/2000),
       DECODE(TRUNC(salary/2000, 0), 
                                                0, 0.00
                                                1, 0.09
                                                2, 0.20
                                                3, 0.30
                                                4, 0.40
                                                5, 0.42
                                                6, 0.44
                                                   0.45) AS "Impuesto Salarial"
FROM hr.employees 
WHERE department_id = 80
/*En este ejemplo, determinamos la tasa de impuestos para cada empleado del departamento 80 basándonos en el salario mensual. Las tasas de impuestos son:
Rango de Salarios Mensuales Tasa de Impuestos
$0.00–1,999.99 0%
$2,000.00–3,999.99 9%
$4,000.00–5,999.99 20%
$6,000.00–7,999.99 30%
$8,000.00–9,999.99 40%
$10,000.00–11,999.99 42%
$12,200.00–13,999.99 44%
$14,000.00 o más 45%
*/
_____________________________________________________________________________________
Con esta 3ra Parte, terminamos las Funciones de una Fila SQL.

---
_____________________________________________________________________________________
_____________________________________________________________________________________
Fuente: Base de Datos Oracle 10g: Conceptos Fundamentales de SQL 1

lunes, 9 de mayo de 2016

Las Fechas y sus Funciones-(Funciones de una Fila SQL, Parte 2)

Objetivos: 
•Utilizar funciones de fecha en Sentencias SQL.
NOTA: Usamos como ejemplo la base de datos: ORCL, la cual viene por defecto en cualquier versión de ORACLE.
_____________________________________________________________________________________
Manejo de las Fechas.
Formato de Fecha de Oracle
La base de datos Oracle almacena las fechas en un formato numérico interno, que representa el siglo, el año, el mes, el día, las horas, los minutos y los segundos.

El formato de visualización y de entrada de ORACLE(por defecto) para cualquier fecha es DD-MON-RR. Las fechas válidas van del 1 de enero de 4712 a.C. al 31 de diciembre de 9999 d.C.

Las fechas en el campo HIRE_DATE de la tabla Employees se muestran en formato DD-MON-RR(por defecto). Sin embargo, las fechas no se almacenan en la base de datos en este formato. Se almacenan todos los componentes de fecha y hora por separados. Así pues, aunque una fecha como 17-JUN-87 se muestra como día, mes y año, también hay información de hora y de siglo asociada a la fecha. Los datos completos podrían ser 17 de junio de 1987, 5:10:43 PM.

Esta fecha se almacena internamente así:
SIGLO AÑO MES DÍA HORA MINUTO SEGUNDO
19 87 6 17 17 10 43
Siglos y el Año 2000 

Al insertar un registro con una columna de fecha en una tabla, la información de siglo se selecciona en la función SYSDATE. Sin embargo, cuando la columna de fecha se muestra en la pantalla, el componente de siglo no se muestra (por defecto). 

El tipo de datos DATE almacena siempre la información de año como número de cuatro dígitos internamente: dos dígitos para el siglo y dos para el año. Por ejemplo, la base de datos Oracle almacena el año como 1987 ó 2004, y no simplemente como 87 ó 04.

Función SYSDATE
SYSDATE es una función de fecha que devuelve la fecha y hora actual del servidor de bases de datos. Puede utilizar SYSDATE igual que cualquier otro nombre de columna. Por ejemplo, puede mostrar la fecha actual seleccionando SYSDATE en una tabla. Se suele seleccionar SYSDATE en una tabla ficticia denominada DUAL

Ejemplo:
Muestre la fecha actual mediante la tabla DUAL
SELECT 
            SYSDATE
FROM DUAL;
--OUTPUT: 16/05/2016 01:46:28 p.m. -- Mi fecha y hora.
--
Operaciones Aritméticas con Fechas.
Como la base de datos almacena fechas como números, puede realizar cálculos mediante operadores aritméticos como la suma o la resta. Puede sumar y restar constantes numéricas además de fechas. 

Puede utilizar las siguientes operaciones:
Operación Resultado Descripción
fecha + número
Fecha
Suma un número de días a una fecha
fecha – número
Fecha
Resta un número de días a una fecha
fecha – fecha
Número de días:
Resta una fecha a otra
fecha + (número/24)
Fecha
Suma un número de horas a una fecha
Ejemplo:
SELECT last_name,
       (SYSDATE-hire_date)/7 AS "Semanas Trabajadas",
       SYSDATE+3 "Fecha mas 3 Dias",
       SYSDATE-3 "Fecha menos 3 Dias",
       SYSDATE-(SYSDATE+6) "Fecha menos (Fecha mas numero de días)"    
FROM employees
WHERE  department_id = 60;
/* En el pasado ejemplo se muestra el nombre de cada empleado del departamento 60, luego a la fecha actual se le resta la fecha de contratación y todo eso se divide por 7 para así determinar el numero de semanas que ha trabajado dicho empleado, la tercera columna muestra la fecha actual mas 3 días, en la 4ta a la misma fecha se le resta 3 días y en la ultima columna a la fecha actual se le resta la (fecha actual mas 6 días). Las ultimas 3 columnas no tienen relación con las 2 primeras. Como notan: si se resta una fecha mas actual a una mas antigua el resultado seria negativo*/
_____________________________________________________________________________________
Funciones de Fecha.
Función                          Resultado
MONTHS_BETWEEN  Número de meses entre dos fechas
ADD_MONTHS Agrega meses de calendario a una fecha
NEXT_DAY Día siguiente a la fecha especificada
LAST_DAY Último día del mes
ROUND  Redondea la fecha
TRUNC Trunca la fecha
EXTRACT
Extrae una porción(DÍA, MES O AÑO) de una fecha dada.
Las funciones de fechas operan en fechas de Oracle. Todas las funciones de fecha devuelven un valor del tipo de datos DATE excepto MONTHS_BETWEEN y EXTRACT, que devuelven un valor numérico. 
MONTHS_BETWEEN(date1, date2): Busca el número de meses entre date1 date2. El resultado puede ser positivo o negativo. Si date1 es posterior a date2, el resultado es positivo; si date1 es anterior a date2, el resultado es negativo. La parte no entera del resultado representa una porción del mes. 
ADD_MONTHS(date, n): Agrega un número n de meses de calendario a date. El valor de n debe ser un entero, si n es negativo se le restaría a la fecha dada el n numero de meses. 
NEXT_DAY(date, 'char'): Busca la fecha del siguiente día de la semana especificado ('char') después de date. El valor de char puede ser un número que represente un día o una cadena de caracteres. 
LAST_DAY(date): Busca la fecha del último día del mes que contiene date.
ROUND(date[,'fmt']): Devuelve date redondeado a la unidad especificada por el modelo de formato fmt. Si se omite el modelo de formato fmtdate se redondeará al día más cercano. 
TRUNC(date[, 'fmt']): Devuelve date con la porción de tiempo del día truncada a la unidad especificada por el modelo de formato fmt. Si se omite el modelo de formato fmtdate se trunca al día más cercano. 
EXTRACT(porción FROM date): Retorna la porción numérica especificada de dateporción podría ser: MONTH, DAY o YEAR. 

Esta lista es un subconjunto de las funciones de fecha disponibles. 
_____________________________________________________________________________________
Usando las Funciones de Fecha.
Función Resultado
MONTHS_BETWEEN ('21/SEP/2014','10/JUL/2012') 26.3548387
ADD_MONTHS ('20/APR/2016',4) '20/AUG/16'
NEXT_DAY   ('08/MAY/2013','THURSDAY') '09/MAY/13'
LAST_DAY   ('01/JUN/2016') '30/JUN/16'
SYSDAY='17/5/2016'
EXTRACT(DAY FROM SYSDATE) 17
EXTRACT(MONTH FROM SYSDATE) 5
EXTRACT(YEAR FROM SYSDATE) 2016
Ejemplo:
SELECT employee_id, hire_date,
MONTHS_BETWEEN (SYSDATE, hire_date) TENURE,
ADD_MONTHS (hire_date, 6) REVIEW,
NEXT_DAY (hire_date, 'WEDNESDAY'), LAST_DAY(hire_date)
FROM hr.employees
WHERE  MONTHS_BETWEEN (SYSDATE, hire_date) > 36;
/*En el ejemplo anterior mostramos el código de empleado, la fecha de contratación, la cantidad de meses que ha trabajado(MONTHS_BETWEEN (SYSDATE, hire_date)), la fecha de cuando se le hizo su primera revision(ADD_MONTHS (hire_date, 6)), la fecha del primer miércoles después que fueron contratados: NEXT_DAY (hire_date, 'WEDNESDAY') y la fecha del último día del mes en cual fueron contratados LAST_DAY(hire_date) de todos lo empleados que tengan mas 36 meses(3 años) en la empresa: MONTHS_BETWEEN (SYSDATE, hire_date) > 36.*/
---
Supongamos que SYSDATE: 17-MAY-2016
Función Resultado
ROUND(SYSDATE,'MONTH') 1-JUN-16
ROUND(SYSDATE,'YEAR') 1-JAN-16
TRUNC(SYSDATE,'MONTH') 1-MAY-16
TRUNC(SYSDATE,'YEAR') 1-JAN-16
Ejemplo:
SELECT last_name, hire_date, 
          ROUND(hire_date, 'MONTH'), TRUNC(hire_date, 'YEAR'
FROM employees 
WHERE hire_date LIKE '%03'
OR hire_date LIKE'%06';
/*En el anterior ejemplo se muestra el empleado, su fecha de contratación, luego su fecha de contratación es redondeada al mes y por último es truncada al año de todos lo empleados contratados en el 2003 o 2006.*/
_____________________________________________________________________________________
A continuación la ultima parte de Funciones de una Fila:
======>>Funciones de Conversión.
Fuente: Base de Datos Oracle 10g: Conceptos Fundamentales de SQL 1.