SlideShare una empresa de Scribd logo
Una guía completa para las
declaraciones de OpenSQL:
tutorial paso a paso con capturas de pantalla
En mi primera publicación de blog sobre SCN, me gustaría dar una descripción general
de la sintaxis de consulta de OpenSQL. A partir de la declaración SELECT más simple,
me gustaría demostrar todos los elementos del lenguaje de OpenSQL, construyendo
gradualmente una consulta de base de datos muy compleja. Para cada paso,
proporcionaré un ejemplo empresarial y una captura de pantalla para que pueda ver el
resultado de cada consulta SELECT. He utilizado la base de datos de demostración de
vuelo disponible en todos los sistemas SAP, por lo que puede probar las consultas por
sí mismo.
Nota: en esta publicación no discutiré temas relacionados con el desempeño en detalle.
Eso haría que esta publicación fuera demasiado larga. Quizás en una publicación futura
¡Vamos a empezar!
Select
Ejemplo 1: la declaración SELECT más simple
Hay tres partes obligatorias de una instrucción SELECT, que básicamente definen qué
desea leer de qué tabla y dónde colocar el resultado:
1. Después de la palabra clave SELECT, debemos especificar los campos del llamado
"conjunto de resultados" ("conjunto de resultados" en la ayuda de SAP). Aquí definimos
qué campos queremos ver en el resultado de la selección. En el Ejemplo 1, ingresamos
“*”, un carácter especial que significa que se devolverán todos los campos de las tablas
definidas. Esta es una característica útil, pero tenga en cuenta que, si selecciona todos
los campos de una tabla que consta de 250 columnas y usa solo cinco de ellas, eso
desperdicia una gran cantidad de recursos de CPU, memoria y red. En este caso, es
mejor enumerar los cinco campos explícitamente (especialmente si selecciona muchos
registros).
2, la cláusula FROM define de qué tabla (s) leer los datos. Aquí debe especificar al
menos una tabla o vista que exista en el Diccionario de datos. En el primer ejemplo solo
accederemos a una tabla, y los ejemplos posteriores usarán más tablas.
3, La cláusula INTO define dónde colocar los resultados, lo que generalmente se
denomina “área de trabajo”. Aquí debe definir el objeto de datos que contendrá el
conjunto de resultados utilizando una de las siguientes opciones:
- INTO x, donde x es una estructura.
- INTO TABLE y, donde y es una tabla interna.
- APENDIENDO LA TABLA z, donde z es una tabla interna. En esto, el conjunto de
resultados se agrega a la tabla interna (sin borrar el contenido existente).
- INTO (a, b, c,…), donde a, b, c, etc.son variables con tipos elementales
Hay varias instrucciones en la ayuda de SAP con respecto a los requisitos previos de
las áreas de trabajo (tipo de datos, etc.) y las reglas de asignación (conversiones
automáticas, etc.) que no quiero copiar y pegar aquí. De todos modos, recomendaría
usar una estructura idéntica a la selección de campo o usar la adición "CAMPOS DE
CORRESPONDIENTE". Esto asignará los campos seleccionados a los campos del
área de trabajo según el nombre del campo (no de izquierda a derecha).
Para todas las construcciones excepto INTO TABLE, si el conjunto de resultados está
vacío, el objetivo permanece sin cambios.
Sugerencia: la cláusula INTO se puede omitir en un caso especial, cuando usa una
función de grupo para contar el número de líneas que coinciden con la cláusula
WHERE. En este caso, la variable de sistema SY-DBCNT contendrá el número de
registros encontrados. Vea el ejemplo 5.
Nota: Falta la cláusula INTO en las capturas de pantalla porque la herramienta que he
usado la genera automáticamente. De todos modos, todos los ejemplos usarían la
variante INTO TABLE para buscar todos los registros coincidentes a la vez.
Requisito comercial: queremos seleccionar todos los datos para 100 reservas de la
tabla de reservas. Realmente simple, ¿verdad?
¿Cómo lograrlo? Simplemente defina "*" después de la palabra clave SELECT,
especifique la tabla SBOOK en la cláusula FROM y limite el número de registros
obtenidos mediante la cláusula "UP TO N ROWS". Esto se puede usar para definir el
número máximo de líneas que queremos que devuelva la consulta. Esto se usa
generalmente para verificaciones de existencia (HASTA 1 FILA), pero en este ejemplo
hemos limitado la consulta para que devuelva un máximo de 100 registros. A menos
que especifique la cláusula ORDER BY, esto devolverá 100 registros arbitrarios, por lo
que no puede saber qué 100 devolverá.
Captura de pantalla 1: Simplemente seleccione 100 reservas de la mesa SBOOK
Where
Ejemplo 2: agregar una cláusula WHERE y una combinación de tabla
La cláusula WHERE
Por lo general, las instrucciones SELECT no leen todo el contenido de una tabla (las
excepciones típicas son pequeñas tablas de personalización que contienen algunos
registros), sino que devuelven solo entradas específicas. La cláusula WHERE se usa
para filtrar el conjunto de resultados, o en otras palabras, decirle a la base de datos qué
registros recuperar. Aquí define una expresión lógica que la base de datos evaluará
para cada fila de la base de datos.
Requisito comercial: devolver solo las reservas de Lufthansa (el campo CARRID debe
contener “LH”) y las reservas canceladas no son necesarias (CANCELADO debe ser
igual al espacio).
La base de datos evaluará esta condición para cada registro de la tabla y, si la condición
es verdadera, se colocará en el conjunto de resultados. Puede escribir condiciones
lógicas mucho más complejas como veremos en los siguientes ejemplos. Se puede
vincular cualquier número de expresiones lógicas a una expresión lógica usando
palabras clave AND u OR y el resultado de una expresión lógica se puede negar usando
la palabra clave NOT. Tenga en cuenta el orden de evaluación (asegúrese de utilizar
correctamente los paréntesis). Los operadores simples que se utilizan para comparar
valores de campo son EQ, NE, GT, LT, GE y LE (equivalente a =, <>,>, <,> =, <=).
La tabla se une
La segunda adición interesante en este ejemplo es la combinación de tablas. A menudo,
los datos necesarios para un proceso empresarial específico se almacenan en varias
tablas. Aunque podría ser una opción seleccionar datos de cada tabla usando
comandos SELECT separados y combinar los resultados usando código ABAP
ejecutado en el servidor de aplicaciones, muchas veces es más conveniente y eficaz
usar solo una instrucción SELECT para leer todas las tablas a la vez.
Requisito comercial. leer los datos del cliente de la tabla SCUSTOM para el cliente de
cada reserva.
Esto se logra mediante la denominada "unión de tabla": una construcción que indica a
la base de datos que acceda a una tabla adicional en función de una condición. Esta
llamada "condición de combinación" (o "expresión de combinación") representa el
vínculo lógico entre las dos tablas. En este ejemplo es el número de cliente: para cada
reserva en la tabla SBOOK, la base de datos buscará los datos del cliente en la tabla
SCUSTOM basándose en el número de cliente.
Debido a que usamos "*" para definir los campos del conjunto de resultados y leemos
de dos tablas en este ejemplo, el conjunto de resultados contiene todos los campos de
ambas tablas. Si hay un campo con el mismo nombre en ambas tablas, solo se
devolverá uno (el de la última tabla en la cláusula FROM; cada combinación sobrescribe
el contenido del campo).
Nota: la herramienta que he usado para las capturas de pantalla genera
automáticamente un campo separado en este caso. Esta es la razón por la que puede
ver campos duplicados.
La sintaxis de una condición de unión es casi la misma que en una cláusula WHERE
con algunas diferencias notables que no quiero copiar y pegar aquí desde la Ayuda de
SAP (no puedo usar subconsultas, debo usar AND para vincular expresiones lógicas,
etc.).
Hay dos tipos de combinaciones de tablas en OpenSQL: combinaciones internas y
combinaciones externas. Discutiremos la diferencia en el siguiente ejemplo.
Sugerencia: las sentencias SELECT que utilizan combinaciones de tablas omiten el
almacenamiento en búfer de SAP.
Captura de pantalla 2: agregar una cláusula WHERE y una combinación de tabla
Ejemplo 3: agregar datos de otras dos tablas
Afortunadamente, OpenSQL permite unir varias tablas a la vez: se pueden unir un
máximo de 25 tablas en una instrucción SELECT. Aquí, en este ejemplo, agregamos
datos de dos tablas más: T005T que contiene datos de países y GEOT005S que
contiene información geográfica de regiones.
Requisito comercial: muestre el nombre del país en lugar del código del país y muestre
la latitud y la longitud de la región del cliente.
Una cosa especial en este ejemplo es la condición de combinación de la tabla T005T.
Esta tabla depende del idioma, por lo que se necesita una clave de idioma para obtener
la descripción textual de un país en un idioma específico. Recuerde: la condición de
unión le dice a la base de datos cómo obtener un registro de la tabla B basado en un
registro de la tabla A (A es el lado izquierdo y B es la tabla del lado derecho). Esto es
especial ahora porque usamos el idioma de inicio de sesión del usuario actual del
campo SY-LANGU. Todos los campos de la estructura SY se pueden utilizar en las
condiciones de unión (fecha actual, hora, ID del sistema, etc.) así como en las cláusulas
WHERE y HAVING.
¿Qué pasaría si omitiéramos la especificación de la clave del idioma? La base de datos
devolvería varias filas con la misma información de reserva, cliente y región. ¿Por qué?
Simplemente porque hay más de una entrada en la tabla T005T para el mismo país.
Digamos que tenemos dos entradas para el país 'DE': es 'Deutschland' en alemán y es
'Alemania' en inglés. En el caso de un cliente alemán, el motor de la base de datos
evaluaría la condición de unión (T005T-LAND1 = SCUSTOM-COUNTRY) para ambos
registros, y ambos serían verdaderos, por lo que se devolverían dos filas: una con texto
en inglés y otra con texto en alemán .
Captura de pantalla 3: combinaciones de varias tablas. Observe que todas las líneas
contienen una latitud y una longitud.
Ejemplo 4: Otro tipo de combinación de tabla: combinación externa izquierda
Aquí viene la diferencia entre los dos tipos de combinaciones de tablas en OpenSQL:
la combinación interna y la combinación externa (por ejemplo, "SELECCIONAR * DE
UNA JUNTA INTERNA B" / "SELECCIONAR * DE UNA JUNTA EXTERIOR
IZQUIERDA B").
Básicamente, la diferencia es el comportamiento en caso de que no haya una entrada
correspondiente en la tabla B para un registro en la tabla A. En caso de una combinación
interna, no se colocaría ningún registro en el conjunto de resultados. En el caso de una
combinación externa izquierda, habría un registro en el conjunto de resultados, pero
todos los campos provenientes de la tabla B estarían vacíos.
Este comportamiento es muy fácil de ver en este ejemplo: agregamos coordenadas
geográficas a nuestra consulta en el ejemplo anterior usando una combinación interna.
La tabla GEOT005S contiene coordenadas para las regiones del país. Siempre que no
se encontró un registro en la tabla GEOT005S para la región de un cliente, toda la línea
se eliminó del conjunto de resultados. Es por eso es que solo puede ver clientes con
latitud y longitud que no estén vacías.
En el ejemplo actual, agregamos la latitud y la longitud de la región del cliente utilizando
una combinación externa izquierda. Como puede ver en la captura de pantalla, solo hay
un cliente para el que se devuelven las coordenadas. Para todos los demás registros,
la base de datos no encontró un registro adecuado en GEOT005S, por lo que las
coordenadas están vacías. Si se accede a GEOT005S mediante INNER JOIN, estos
registros se excluirán del conjunto de resultados.
Captura de pantalla 4: combinación de tabla mediante una combinación externa
izquierda. Observe que ahora los clientes con latitud y longitud vacías aparecen en la
lista.
Nota: si ha revisado cuidadosamente la captura de pantalla podría notar que hay un
cliente con una región definida ('IL') pero no se muestran coordenadas. La razón podría
ser que no hay una entrada en GEOT005S para la región 'IL' del país 'EE. UU.', Pero
no es el caso.
De alguna manera, la base de datos de demostración de vuelo estándar contiene
entradas incorrectas que tienen un espacio innecesario. Esta es la razón por la que la
base de datos no encuentra el registro coincidente, ya que 'IL' <> 'IL'.
Captura de pantalla 4 b: entradas incorrectas para la región 'IL' en la tabla GEOT005S
Corregí estas entradas usando esta simple declaración de actualización:
Después de corregir las entradas en la tabla SCUSTOM, la consulta completa las
coordenadas para todos los clientes en la región 'IL':
Captura de pantalla 4 c: combinación de tabla usando una combinación externa
izquierda después de corregir las entradas problemáticas de la base de datos.Observe
que ahora todos los clientes que tienen una región definida tienen las coordenadas
completadas.
Ejemplo 5: agregar una función de grupo simple
Muchas veces, la empresa no está interesada en todos los registros de datos
individuales, pero desea ver una agregación basada en un campo específico. Por
ejemplo, la suma de todas las ventas por vendedor, costos por proyecto, etc. En este
caso tenemos dos opciones: recuperar todos los registros relevantes de la base de
datos y realizar los cálculos en el servidor de aplicaciones usando nuestro propio código
ABAP, o realizar el cálculo utilizando el motor de base de datos.
Requisito comercial: queremos ver el número de reservas que coinciden con nuestros
criterios de selección. (reservas de Lufthansa que no se cancelen).
Para lograr esto usando la base de datos, tenemos que agregar una cláusula GROUP
BY y tenemos que definir la función agregada (también llamada como función de grupo)
COUNT en la cláusula SELECT.
Group by
La cláusula GROUP BY combina grupos de filas en el conjunto de resultados en una
sola fila. En este caso muy simple, queremos ver el número total de reservas, no
desglosado por ningún otro campo.
La función COUNT (*) determina el número de filas en el conjunto de resultados o en el
grupo actual. En este momento no tenemos ningún grupo definido, por lo que en nuestro
caso devuelve el número total de reservas.
Captura de pantalla 5: una función de grupo simple que cuenta el número de reservas
que coinciden con los criterios de selección.
Nota: La función COUNT también se puede utilizar para determinar el número de
valores diferentes de un campo específico en el conjunto de resultados. En este caso,
simplemente ponga el nombre del campo entre paréntesis y agregue la palabra clave
DISTINCT. Por ej. para contar de cuántos países son los clientes, use "COUNT
(DISTINCT country)" en la cláusula SELECT.
Es importante tener en cuenta que las funciones de grupo siempre se realizan después
de la evaluación de la cláusula WHERE. El motor de la base de datos primero lee los
registros que coinciden con la cláusula WHERE, luego forma grupos (vea el siguiente
ejemplo) y luego realiza la función de grupo.
El uso de la cláusula GROUP BY y las funciones agregadas asegura que los agregados
y grupos sean ensamblados por el sistema de base de datos, no por el servidor de
aplicaciones. Esto puede reducir considerablemente el volumen de datos que deben
transferirse desde la base de datos al servidor de aplicaciones. Por otro lado, por
supuesto, esto necesita más recursos de la base de datos.
Sugerencia: Con el uso de GROUP BY, la instrucción SELECT evita el
almacenamiento en búfer de SAP.
Ejemplo 6: definir grupos para las funciones de grupo
Hemos aprendido que las funciones de grupo realizan ciertos cálculos en grupos de
registros de bases de datos. Si no especificamos explícitamente un grupo, entonces
todos los registros en el conjunto de resultados se consideran como un gran grupo,
como en el ejemplo anterior.
Requisito comercial: mostrar el número de reservas (no canceladas de Lufthansa) por
cliente.
En este caso, formamos grupos de registros de base de datos basados en el número
de cliente enumerando el ID de campo en la cláusula group by. Además, tenemos que
ingresar el campo ID de la tabla SCUSTOM en la cláusula SELECT antes de la función
de grupo.
Captura de pantalla 6: Agrupación de filas por ID de cliente. La función de grupo COUNT
se realiza en cada grupo para contar el número de reservas de cada cliente.
Como puede ver, ahora el motor de base de datos devuelve tantos registros como ID
de cliente tengamos en el conjunto de resultados y el número de reservas relevantes
junto a ellos. Exactamente lo que queríamos.
Nota: en todos nuestros ejemplos anteriores, usamos el signo "*" en la cláusula
SELECT (lista de campos). Sin embargo, aquí tenemos que definir explícitamente los
campos necesarios para crear grupos de registros. Es obligatorio agregar el nombre de
la tabla y el signo ~ antes del nombre de un campo de la base de datos, si más de una
tabla tiene un campo con el mismo nombre.
Ejemplo 7: agregar información adicional
Requisito comercial: mostrar campos adicionales en la lista de resultados (nombre,
ciudad, país, código de región, coordenadas).
¿Cómo hacerlo? Simplemente agréguelos a la cláusula SELECT después del número
de cliente antes de la función COUNT. Tenga en cuenta que también debe agregar el
campo a la cláusula GROUP BY, de lo contrario, encontrará un error de sintaxis. Los
campos que usa para formar grupos deben estar en la cláusula SELECT, y nada más
debe estar en la cláusula SELECT que no esté en la cláusula GROUP BY a menos que
sea un argumento de una función de grupo.
Captura de pantalla 6a: se muestran campos adicionales en la lista.
Nota: Es técnicamente posible omitir un campo de la cláusula SELECT, que es parte
de la cláusula GROUP BY, pero realmente no tiene mucho sentido. Por ejemplo, el
conjunto de resultados se agrupará en dos campos, pero solo se mostrará un campo
de agrupación.
Captura de pantalla 6b: omitir el campo ID de conexión de la cláusula SELECT es
sintácticamente correcto, sin embargo, no tiene sentido. Observe que el mismo ID de
operador aparece tantas veces como los ID de conexión existen para él, pero los ID de
conexión no forman parte del conjunto de resultados.
Nota: Ahora podrías preguntarte que en el ejemplo anterior te dije que agregando
campos antes de la función de grupo es como definimos grupos, pero aquí el número
de reservas no cambió. La razón es que hemos agregado campos de tablas que tienen
una relación 1: 1 con el cliente. Un cliente tiene un solo nombre, una ciudad está en un
país y región y tiene un par de coordenadas. Si hubiéramos optado por agregar el
campo Clase de vuelo (Primera clase / Business / Economy), entonces el conjunto de
resultados podría contener más de una línea por cliente: tantas líneas por cliente como
tantos tipos de vuelos haya tenido. Veremos cómo funciona esto en el ejemplo 15.
Ejemplo 8: Definición del orden de los registros en el conjunto de resultados
Puede utilizar la cláusula ORDER BY en una consulta para definir el orden de
clasificación de los registros devueltos. Simplemente enumere todos los campos que
desea utilizar como criterio de clasificación. Puede utilizar las palabras clave
ASCENDING y DESCENDING para cada campo para especificar el modo de
clasificación (ASCENDING es el valor predeterminado, por lo que se puede omitir).
Requisito comercial: mostrar los clientes con más reservas.
¿Qué hacemos ahora? Ordenamos la lista por el resultado de la función COUNT en
orden descendente y luego por el nombre del cliente.
Captura de pantalla 7: el conjunto de resultados se ordena mediante la cláusula ORDER
BY.
Como puede ver, hay varios clientes que tienen más de diez reservas (no canceladas,
Lufthansa).
Nota: Si todos los campos clave están en la lista de campos y se especifica una única
tabla de base de datos después de FROM (no una vista o expresión de combinación),
la adición PRIMARY KEY se puede usar para ordenar el conjunto de resultados en
orden ascendente según la clave primaria de la mesa.
Ejemplo 9: filtrado basado en una función de grupo
Requisito comercial: el jefe solo está interesado en los clientes que tienen más de diez
reservas de Lufthansa no canceladas.
¿Cómo hacemos esto? Supongo que la primera idea sería agregar una nueva condición
a la cláusula WHERE para filtrar registros donde la función COUNT es mayor que diez.
Sin embargo, esto no funcionará debido al lenguaje OpenSQL (y SQL en general).
La razón es que la cláusula WHERE filtra los registros de la base de datos antes de
que el motor de la base de datos cree los grupos. Una vez creados los grupos, se
calculan las funciones de grupo y se crea el conjunto de resultados. La cláusula WHERE
no se puede utilizar para filtrar en función de los resultados de la función de grupo.
En casos como estos, se debe utilizar la cláusula HAVING. Esto es similar a la cláusula
WHERE, pero la diferencia es que se evalúa después de que se crean los grupos y se
realizan las funciones de grupo. En pocas palabras: para filtrar en función del resultado
de las funciones de grupo, se debe usar la cláusula HAVING (también llamada
condición de grupo).
Captura de pantalla 8: uso de la cláusula HAVING para filtrar el conjunto de resultados
en función de las funciones de grupo.
Como puede ver en la captura de pantalla, ahora solo se devuelven 23 registros,
aunque hemos permitido tener 100 registros mediante el uso de la adición HASTA N
FILAS. Esto significa que hay 23 clientes que tienen más de diez reservas de Lufthansa
no canceladas.
Nota: Si no especifica ningún grupo usando la cláusula GROUP BY, la cláusula
HAVING considerará el conjunto de resultados completo agrupado en una línea. Para
un ejemplo rápido, suponga que tenemos 10 registros en la tabla SCARR. La consulta
"SELECT COUNT (*) FROM scarr HAVING count (*) GT 0" devolverá una sola línea
con el número de registros en la tabla, pero la consulta "SELECT COUNT (*) FROM
scarr HAVING count (*) GT 10” No devolverá ninguna línea (conjunto de resultados
vacío).
Subconsultas
Ejemplo 10: uso de subconsultas
La posibilidad de combinar varias sentencias SELECT en una es una característica muy
útil en OpenSQL. Esto se usa principalmente cuando no conoce exactamente los
criterios de filtro durante el tiempo de diseño o cuando tiene que usar una comparación
con un valor calculado dinámicamente.
Requisito comercial: la lista debe incluir solo a los clientes que nunca hayan cancelado
un vuelo (cualquier aerolínea, no solo Lufthansa). A primera vista, lógicamente podría
preguntar que esto ya está hecho, ya que hemos "cancelado el espacio de EQ" en
nuestra cláusula WHERE. Esto no es correcto, porque esto solo influye en nuestra
función de grupo, por lo que solo se cuentan las reservas no canceladas. Esto significa
que, si un cliente tiene 20 reservas con una cancelada, estará en nuestra lista con 19
reservas. De acuerdo con nuestro requisito, no queremos que este cliente esté en
nuestra lista, entonces, ¿cómo lo logramos?
Una manera fácil de resolver esto es agregar una subconsulta a nuestra cláusula
WHERE que verifica si hay una reserva cancelada para el cliente.
Subconsultas en general
Básicamente, una subconsulta es una instrucción SELECT entre paréntesis que se usa
en una expresión lógica. No es necesario tener una cláusula INTO porque el motor de
la base de datos procesará el resultado de la subconsulta.
¿Cómo se evalúan los resultados de las subconsultas? Esto depende de si la
subconsulta está correlacionada o no. Si una subconsulta usa campos de la instrucción
SELECT circundante en su condición WHERE, se denomina subconsulta
correlacionada. En este caso, el resultado de la subconsulta se evaluará para cada
línea en el conjunto de resultados de la instrucción SELECT circundante (en cuya
cláusula WHERE se coloca la subconsulta). Esto implica que la subconsulta es para
cada registro en el conjunto de resultados de la instrucción SELECT circundante. Por
otro lado, una subconsulta sin ninguna referencia a la instrucción SELECT circundante
se ejecuta solo una vez.
Hay diferentes operadores que se pueden usar con subconsultas, usaremos el
operador "EXISTS" (negado) en este ejemplo. Discutiré los demás en el Ejemplo 13.
Las subconsultas se pueden anidar, lo que significa que puede poner una subconsulta
en la cláusula WHERE de una subconsulta. Veremos un ejemplo de esto más adelante
en el Ejemplo 13.
Ahora, tome el ejemplo actual: necesitamos verificar si un cliente tiene una reserva
cancelada, por lo que tenemos que crear una relación entre el ID de cliente en el
conjunto de resultados de nuestra declaración SELECT externa y la subconsulta (por
lo que usamos una subconsulta correlacionada). Esto se hace agregando una condición
a la cláusula WHERE de la subconsulta para que coincida con los ID de cliente.
Captura de pantalla 9: uso de una subconsulta. Como puede ver, ahora solo se
devuelven 20 registros, por lo que tres clientes tuvieron un vuelo cancelado en nuestra
lista anterior.
Alias
Alias de tabla
Observe que aquí debemos usar los llamados "alias de tabla" porque seleccionamos
de la misma tabla tanto en la consulta circundante como en la subconsulta. Esto
significa que de alguna manera debemos definir explícitamente el nombre de la tabla
para los campos que se compararán, de lo contrario, el motor de la base de datos no
sabría a qué campo de la tabla nos referimos. Esto se hace con el uso de alias de
tablas. Básicamente, puede dar un nombre a sus tablas y hacer referencia a ellas
utilizando el alias. Aquí definí "sq" como un alias para la subconsulta. Debe utilizar el
carácter ~ entre el alias de la tabla y el nombre del campo (y, por supuesto, entre el
nombre de la tabla y el nombre del campo como en los ejemplos anteriores).
Notas:
• Las subconsultas no se pueden utilizar al acceder a las mesas de billar o las
mesas de grupo.
• la cláusula ORDER BY no se puede utilizar en una subconsulta.
• Si se utiliza una subconsulta, la instrucción Open SQL omite el almacenamiento
en búfer de SAP.
Nota: las subconsultas también se pueden usar en la cláusula HAVING como se ve en
el ejemplo 14.
Sugerencia: podríamos haber resuelto el requisito sin una subconsulta correlacionada.
En este caso, la subconsulta seleccionaría a todos los clientes que tenían una reserva
cancelada, y la declaración SELECT circundante verificaría a cada cliente si está en el
conjunto de resultados de la subconsulta:
Ejemplo simplificado:
SELECT ... WHERE customid NOT IN (seleccione customid del sbook donde se canceló EQ
'X'). es igual a SELECT ... WHERE no existe (seleccione bookid de sbook como sq donde sq
~ customid EQ sbook ~ customid y EQ cancelado 'X')
Ejemplo 11: operadores especiales
En todos los ejemplos anteriores solo hemos utilizado el operador 'EQ' (igual que '=') y
el 'GT' (> =) para comparar valores de campo. Sin embargo, también hay otros más
complejos.
ENTRE
Este operador es muy simple, es básicamente “<=” y “> =” juntos.
Requisito comercial: excluir de nuestra lista solo a los clientes que tengan reservas
canceladas en el primer trimestre de 2005.
La sintaxis para esto es “campo ENTRE valor1 Y valor2”.
Sugerencia: desde la perspectiva comercial, esperamos más clientes en el conjunto de
resultados, ya que excluimos menos clientes debido a una subconsulta más restrictiva.
Captura de pantalla 10: uso del operador BETWEEN. Como puede ver, hay 21 clientes
en nuestra lista, por lo que hay un cliente que aparece nuevamente (tuvo cancelación
antes o después del primer trimestre de 2005).
IGUAL QUE
Esta expresión es una herramienta muy flexible para las comparaciones de cadenas de
caracteres basadas en un patrón. El patrón se puede definir utilizando caracteres
comodín: "%" representa cualquier cadena de caracteres (incluso una vacía) y "_"
representa cualquier carácter individual. La expresión LIKE distingue entre mayúsculas
y minúsculas y los caracteres en blanco al final del patrón se ignoran (LIKE '__' es igual
a LIKE '__').
Requisito comercial (bastante extraño ...): restringir aún más nuestra lista para que solo
contenga clientes con un nombre que comience con "A".
Agregamos “nombre LIKE 'A%'” a la cláusula WHERE para lograr esto.
Captura de pantalla 11: uso del operador LIKE para filtrar la lista según el nombre del
cliente.
Nota: ¿Qué hacer si queremos buscar registros que contengan '_' en un campo
específico? Dado que este es un símbolo reservado, tenemos que usar la adición
ESCAPE, que permite definir un carácter de escape. Este carácter de escape cancela
las funciones especiales de los caracteres comodín (simplemente coloque el carácter
de escape antes del carácter comodín que se va a cancelar).
Un ejemplo rápido: seleccione todos los números de material que contienen un guión
bajo:
Enfoque incorrecto (devuelve todos los números de material):SELECT matnr FROM
mara donde matnr LIKE '% _%'
Buen enfoque: SELECCIONE matnr FROM mara donde matnr LIKE '% ~ _%' ESCAPE
'~'
Sugerencia no es posible especificar un campo de tabla como patrón.
Requisito comercial (aún más extraño): ahora solo queremos ver a los clientes con un
nombre que comience con 'A' y que tenga la 'd' como tercera letra.
Captura de pantalla 12: uso del operador LIKE con los dos caracteres especiales “%” y
“_”. Como puede ver, todavía tenemos tres clientes que cumplen con todos nuestros
criterios de selección.
EN
Este operador le permite comparar un campo con un conjunto de valores fijos. Esto es
útil ya que puede reemplazar una expresión más larga y mucho menos legible:
“Field IN ('01, '03, '05')” es igual al mucho más largo “field EQ '01' o field EQ '02' o field
EQ '03'”
Requisito comercial: extender nuestra selección a los clientes de American Airlines y
United Airlines también.
Captura de pantalla 13: uso del operador IN para contar las reservas de otras aerolíneas
también. Como era de esperar, ahora tenemos muchos más clientes que cumplen con
los criterios de selección menos restrictivos.
Nota: el operador IN también se puede utilizar con una tabla de selección, como se ve
en el capítulo 17.
Ejemplo 12: Otras funciones de grupo
Hasta ahora, solo hemos utilizado la función de grupo COUNT para contar el número
de reservas que coinciden con nuestros criterios de selección. Hay un total de cinco
funciones de grupo disponibles en OpenSQL. Los cuatro restantes que aún no hemos
visto son todos cálculos matemáticos: SUM, MIN, MAX y AVG que calculan el total,
mínimo, máximo y promedio de un campo respectivamente.
Existen algunas restricciones relacionadas con el uso de funciones de grupo:
• Si la adición PARA TODAS LAS ENTRADAS se usa delante de WHERE, o si
las tablas de grupo o agrupaciones se enumeran después de FROM, no se
pueden usar otras expresiones agregadas además de COUNT (*).
• Las columnas del tipo STRING o RAWSTRING no se pueden utilizar con
funciones agregadas.
• Los valores nulos no se incluyen en el cálculo de las funciones agregadas. El
resultado es un valor nulo solo si todas las filas de la columna en cuestión
contienen el valor nulo.
Requisito comercial: el jefe quiere ver el precio total, promedio, mínimo y máximo de la
reserva para cada cliente (en la moneda de la aerolínea).
Captura de pantalla 14: uso de todas las funciones de grupo (MIN, MAX, SUM, AVG,
COUNT).
Nota: al igual que con la función COUNT, la palabra clave DISTINCT se puede usar
para realizar la función de grupo solo en valores distintos (por lo que el resultado de
SUM (DISTINCT A) para dos registros que tienen el valor 10 en un campo A sería 10).
Nota: el tipo de datos para AVG y SUM debe ser numérico. El tipo de datos MIN, MAX
y SUM es el tipo de datos del campo de tabla correspondiente en el Diccionario ABAP.
Las expresiones agregadas con la función AVG tienen el tipo de datos FLTP y las que
tienen COUNT tienen el tipo de datos INT4.
Sugerencia: la herramienta que he usado para la demostración reemplaza los tipos de
campo de estas funciones agregadas para una visualización más fácil de usar (en lugar
de la notación exponencial).
Ejemplo 13: subconsultas anidadas
Las subconsultas se pueden anidar, lo que significa que puede poner una subconsulta
en la cláusula WHERE de una subconsulta. Se permite un máximo de diez sentencias
SELECT dentro de una consulta de OpenSQL (una sentencia SELECT puede tener un
máximo de nueve subconsultas).
Requisito comercial: excluir solo a los clientes que hayan cancelado reservas en el
primer trimestre de 2005 y el idioma de la agencia de viajes es el inglés, donde se
realizó la cancelación. Bastante incómodo, pero tenía que averiguar algo
Podemos implementar esta lógica usando una subconsulta anidada: agregamos este
criterio a la cláusula WHERE de la subconsulta externa (seleccione todos los números
de agencia donde el idioma es el inglés). Esto es diferente de nuestra subconsulta
anterior, debido a la palabra clave que usamos para evaluarla.
Expresiones lógicas para subconsultas
- EXISTS: esto es lo que hemos usado en nuestra primera subconsulta. Esto devuelve
VERDADERO si la subconsulta devuelve algún registro (uno o más) en su conjunto de
resultados; de lo contrario, devuelve FALSO.
- EQ, GT, GE, LT, LE: estos operadores se pueden utilizar para comparar un campo
con el resultado de la subconsulta. Si la subconsulta devuelve más de una fila,
obviamente el motor de la base de datos no sabrá cuál usar para la comparación: se
producirá una excepción no detectable.
- Para utilizar subconsultas que devuelven varias filas, debe utilizar el operador IN
(comprueba si el campo es igual a alguno de los valores devueltos por la subconsulta)
o una de las palabras clave ALL, ANY y SOME junto con EQ, GT, GE, LT o LE. Estos
influirán en la comparación de una manera bastante autoexplicativa: la comparación se
llevará a cabo con todos los registros devueltos por la subconsulta, y la comparación
devolverá VERDADERO si todos (TODOS) o al menos uno (CUALQUIER, ALGUNOS)
registros regresan VERDADERO para la comparación. No hay diferencia entre las
palabras clave ALGUNAS y CUALQUIER.
¿Qué resultado esperamos? Dado que nuestra subconsulta externa se usa para filtrar
clientes con reservas canceladas, una subconsulta menos restrictiva (lograda por la
subconsulta anidada) significaría más clientes en nuestra lista. Prácticamente: cuantas
menos agencias incluyamos en nuestra búsqueda de cancelaciones, más clientes
obtenemos en la lista.
Captura de pantalla 15: anidación de subconsultas. Como puede ver, en realidad
tenemos un cliente más en nuestra lista, que canceló su reserva en una agencia donde
el idioma no es el inglés.
Ejemplo 14: HAVING y GROUP BY en una subconsulta
Requisito comercial: excluir únicamente a los clientes que tengan al menos tres
cancelaciones (vuelo de Lufthansa en el primer trimestre de 2005 en una agencia de
habla inglesa).
Como tenemos que contar el número de estas reservas, tenemos que utilizar la función
de grupo COUNT y agrupar las reservas por ID de cliente. De esta forma obtenemos el
número de reservas coincidentes por cliente. Luego, simplemente agregamos la
cláusula HAVING para asegurarnos de que solo excluimos de nuestra consulta principal
a los clientes que tienen más de dos cancelaciones.
Podemos esperar tener más clientes en nuestro conjunto de resultados, ya que
tenemos una subconsulta más restrictiva que usamos para filtrar los clientes.
Captura de pantalla 16: uso de las cláusulas GROUP BY y HAVING en una subconsulta.
Como puede ver, tenemos dos clientes más en nuestra lista (que tienen una o dos
reservas canceladas coincidentes).
Ejemplo 15: Extendamos la cláusula GROUP BY
Requisito comercial: incluya solo a los clientes que tengan más de 10 reservas para la
misma aerolínea. No importa cuál, pero deberían ser más de diez.
Hasta ahora hemos contado todas las reservas de los clientes que cumplen con todos
nuestros criterios (por ejemplo, tener más de 10 reservas de cualquier aerolínea). Esto
podría ser como si alguien tuviera 5 reservas para Lufthansa, 5 para American Airlines
y 2 para United Airlines (el total es superior a 10). Ahora queremos ver algo así como
11 para Lufthansa.
Es muy simple resolver esto agregando el código de la aerolínea (CARRID) a la lista de
campos de nuestra consulta principal. Recuerde, el motor de la base de datos creará
grupos de registros basados en todos los campos enumerados antes de la primera
función de grupo en la lista de campos (cláusula SELECT). Si agregamos aquí el código
de la aerolínea, se harán grupos por aerolínea para cada cliente y la función COUNT
contará el número de reservas por cliente y aerolínea.
¿Qué cambios esperamos en nuestro conjunto de resultados? Debería haber muchos
menos clientes en nuestra lista, porque deben tener más de diez reservas para la misma
aerolínea.
Captura de pantalla 17: agregando el ID de operador a la cláusula GROUP BY (y
también a la cláusula SELECT).
El resultado muestra exactamente esto: solo tenemos tres clientes (muy leales) que
cumplen con nuestros criterios de selección. Tenga en cuenta que la mayor cantidad
de reservas ahora es solo 12, mientras que en el ejemplo anterior era 19.
Joint
Ejemplo 16: Regresar a LEFT OUTER JOIN
Para que se muestren algunas coordenadas en la lista de resultados, realizamos dos
cambios:
- cambiar la condición DÓNDE de la consulta principal: en lugar de comprobar el
nombre del cliente y el código de la aerolínea, seleccionamos clientes de EE. UU. De
esta manera tendremos muchos más clientes en nuestra lista (100 que está limitado
por la adición de HASTA N FILAS) y como son de los EE. UU., Veremos algunos
códigos de región para los clientes (las coordenadas se mantienen para las regiones
de EE. UU.).
- elimine la cláusula HAVING para incluir a los clientes con menos de 11 reservas
coincidentes.
Captura de pantalla 18: primer cambio: quitar el cheque para tener al menos diez
reservas.
Captura de pantalla 19: segundo cambio: seleccionar clientes de EE. UU.
Ahora puede volver a ver el comportamiento de LEFT OUTER JOIN: se rellenan las
coordenadas para todos los registros, donde se rellena el código de región y se
encuentran las coordenadas para la región en la tabla GEOT005S.
Ejemplo 17: uso de una tabla de selección en la cláusula WHERE
Las tablas de selección se utilizan para definir selecciones complejas en un campo. Se
utilizan principalmente junto con las pantallas de selección (utilizando la instrucción
SELECT-OPTION). Cualquier selección que haga el usuario en la interfaz de usuario
se convertirá en una expresión lógica compleja utilizando los operadores con los que
hemos trabajado en este tutorial (EQ, GT, LE, GE, LT, NE, BETWEEN, NOT, etc.). Esta
conversión la realiza el motor OpenSQL de forma automática.
Para comparar los valores de un campo de tabla con una tabla de selección, debe
utilizar el operador "IN".
Requisito empresarial: solo se cuentan las reservas de clase ejecutiva y económica ('C'
e 'Y') en un intervalo de tiempo complejo.
Captura de pantalla 20: realización de selecciones complejas mediante tablas de
selección. Observe la palabra clave "IN" utilizada como operador de comparación.
Nota: la herramienta utilizada para esta demostración ofrece una interfaz de usuario
para definir las tablas de selección como en las pantallas de selección. Además, la
cláusula WHERE generada es visible en el lado derecho, junto a las tablas de selección
R_SBOOK_FLDATE y R_SBOOK_CLASS.
Ejemplo 18: La construcción "PARA TODAS LAS ENTRADAS EN"
Esta construcción se usa ampliamente en ABAP y es similar a una combinación de tabla
de una manera que se usa para leer datos de una tabla para registros que ya tenemos
(generalmente seleccionados de otra tabla o devueltos por un módulo de función). Sin
embargo, existen grandes diferencias entre los dos constructos.
La construcción "PARA TODAS LAS ENTRADAS EN la tabla interna" le permite usar
una tabla interna como base de su selección, pero no como una tabla de selección del
Ejemplo 17. Si usa esta adición, puede (en realidad, debe) consultar los campos de la
tabla interna en la cláusula FOR ALL ENTRIES IN para realizar la comparación con los
campos de la (s) tabla (s) de la base de datos que se están leyendo. Naturalmente, los
campos utilizados en la comparación deben tener tipos de datos compatibles.
Como esta construcción es específica de ABAP, existe un mecanismo que traduce el
comando OpenSQL a una o más declaraciones SQL nativas. En realidad, las cláusulas
WHERE que se pasarán al motor de la base de datos se generarán en función del
contenido de la tabla interna y la cláusula WHERE que defina. Hay varios parámetros
de perfil que influyen en esta conversión, que puede verificar en la Nota SAP 48230 -
Parametrización para la instrucción SELECT ... FOR ALL ENTRIES .
La principal diferencia entre las uniones de tablas y esta construcción es que las
uniones de tablas las realiza el servidor de base de datos y todos los datos se pasan al
servidor de aplicaciones a la vez. Por otro lado, en el caso de una construcción FOR
ALL ENTRIES IN, la cláusula WHERE completa se evalúa para cada fila individual de
la tabla interna. El conjunto de resultados de la instrucción SELECT es la unión de los
conjuntos de resultados producidos por las evaluaciones individuales. Es muy
importante tener en cuenta que los registros duplicados se eliminan automáticamente
del conjunto de resultados (pero en el servidor de aplicaciones y no en el servidor de la
base de datos).
Sintácticamente, hay una diferencia en que debe usar el signo "-" en lugar del signo "~"
entre el nombre de la tabla interna y el nombre del campo de la tabla interna en la
cláusula WHERE.
Nota muy importante: si la tabla interna a la que se hace referencia está vacía, la
cláusula WHERE completa se ignora y todas las líneas de la base de datos se colocan
en el conjunto de resultados. Siempre haga una verificación en la tabla interna antes de
ejecutar una consulta de selección usando esta construcción.
Requisito comercial: lea la información de la aerolínea de todas las aerolíneas que
aparecen en nuestra lista.
¿Cómo implementar esto? Ya tenemos una instrucción SELECT del ejemplo anterior,
así que cree una segunda instrucción SELECT usando la construcción FOR ALL
ENTRIES IN. Simplemente agregue el ID del operador como un enlace en la cláusula
WHERE (similar a la condición de combinación en el caso de combinaciones de tablas)
y eso es todo.
Captura de pantalla 21: uso de la construcción “PARA TODAS LAS ENTRADAS EN la
tabla interna”.
Nota: la herramienta que he usado para la demostración usa "external_table" como el
nombre de la tabla interna. El contenido proviene de la consulta de selección del
ejemplo 17.
Nota: A partir de la versión 6.10, se puede especificar la misma tabla interna después
de FOR ALL ENTRIES y después de INTO. Sin embargo, tenga cuidado porque en este
caso se borrarán todos los campos de la tabla interna que no estén llenos por la consulta
SELECT.
Nota: en cuanto al rendimiento, hay discusiones interminables sobre SCN si una
combinación de tabla o la construcción FOR ALL ENTRIES IN es mejor. Realmente
depende de la configuración de almacenamiento en búfer de las tablas que seleccione,
los campos que use para combinaciones y selecciones, los índices que están
disponibles, la cantidad de registros en ambas tablas, los parámetros de perfil del
sistema SAP, etc. En general, prefiero las combinaciones ya que es una “herramienta”
que está diseñada especialmente con el propósito de leer datos de múltiples tablas al
mismo tiempo y se hace en la capa de la base de datos. Por supuesto, ciertas
situaciones están en contra de una mesa combinada. Además, no tiene otra opción si
usa un método BAPI / Módulo de función / Clase para obtener registros de la base de
datos, ya que obviamente en ese caso no puede usar una combinación de tabla, pero
debe usar la construcción FOR ALL ENTRIES IN.
Otras palabras clave
ÚNICO y PARA ACTUALIZAR
Si usa la adición ÚNICA, el conjunto de resultados contendrá un registro como máximo.
Si las cláusulas restantes de la instrucción SELECT devuelven más de una línea, solo
se devolverá la primera.
La adición FOR UPDATE se puede usar solo con la adición SINGLE, que puede usar
para establecer un bloqueo exclusivo para el registro seleccionado. Sin embargo, esto
rara vez se usa y también prefiero usar los módulos de función de bloqueo por
separado.
Nota: La adición SINGLE no está permitida en una subconsulta y la cláusula ORDER
BY no se puede usar junto con ella.
CLIENTE ESPECIFICADO
Esta adición desactiva el manejo automático de clientes de Open SQL. Cuando se
utiliza la adición CLIENTE ESPECIFICADO, la primera columna de las tablas de la base
de datos dependiente del cliente se puede especificar en las cláusulas WHERE y
ORDER BY.
ELIMINANDO EL BÚFER
Esta adición hace que la instrucción SELECT omita el almacenamiento en búfer de SAP
y lea directamente desde la base de datos y no desde el búfer en el servidor de
aplicaciones.
FINALIZAR
Una instrucción SELECT puede recuperar registros de la base de datos uno por uno
(funcionando como un bucle usando la palabra clave INTO), o juntos a la vez (esto se
llama "búsqueda de matriz" y se usa con la palabra clave INTO TABLE / APPENDING
TABLE). En el primer caso, la sentencia ENDSELECT cierra el ciclo iniciado con
SELECT. Ambas construcciones obtienen el mismo resultado.
Fuera del alcance de esta publicación de blog
Sugerencias de base de datos
Básicamente, el uso de sugerencias se usa para especificar cómo el motor de la base
de datos debe ejecutar nuestra consulta. Si omite esto, el motor de base de datos
utilizará su propio optimizador para determinar la mejor estrategia para ejecutar la
instrucción SELECT. El uso de sugerencias para anular esta estrategia predeterminada
es bastante frecuente fuera de SAP, pero rara vez se usa con ABAP.
Una razón es que no muchos desarrolladores saben que es posible usar sugerencias
con declaraciones de OpenSQL (no solo con las nativas). Además, existen ciertos
inconvenientes (problemas durante la actualización de la base de datos o el cambio del
servidor de la base de datos) y existe una mayor posibilidad de errores humanos.
Hay una muy buena descripción general de las sugerencias de la base de datos en la
nota de SAP 129385 - Sugerencias de la base de datos en Open SQL
Especificación de token dinámico
Es posible ensamblar declaraciones OpenSQL durante el tiempo de ejecución.
Entonces, en lugar de codificar una declaración SELECT estática, puede usar variables
de tipo carácter para contener las cláusulas SELECT, FROM, WHERE, etc. Esto puede
resultar útil en ciertos casos, pero tiene desventajas con respecto al rendimiento, la
capacidad de mantenimiento y la legibilidad del código. Además, existen ciertas
restricciones dependientes de la versión de SAP sobre los elementos de sintaxis
permitidos. Hay algunos materiales interesantes en SCN y otros sitios que tratan este
tema.
Conclusión
Como puede ver, aunque Open SQL es un subconjunto muy limitado del lenguaje SQL
moderno, aún le permite ejecutar consultas bastante complejas. En la mayoría de los
casos, toda la lógica empresarial de un informe complejo no se puede mapear en una
sola consulta de selección; sin embargo, si conoce las posibilidades que tiene, puede
escribir un código de programa mucho más elegante y compacto con un mejor
rendimiento.
Gracias por leer y divertirse usando Open SQL.
Adición del moderador: el comentario a continuación agrega enlaces a información actualizada
muy útil.
Thomas Fiedler 28 de mayo de 2014 8:48 a. M.
Hola Tamas,
muy buena descripción general sobre el tema Open SQL. Hay mucho más en la carretera en NW 7.40.
Allí dimos un gran paso adelante con respecto a SQL en ABAP, por ejemplo, una herramienta
completamente nueva para definir vistas de bases de datos:
Nuevas funciones de modelado de datos en SAP NW ABAP 7.4 SP5
Y también en el lado de las herramientas tenemos mucho más. ¿Conoce las herramientas ABAP
basadas en Eclipse con la vista previa de datos para tablas de bases de datos?
Presentación de la vista previa de datos en ADT 2.19
Saludos cordiales,
Thomas.

Más contenido relacionado

PPT
4 to referencia relativa
PPTX
4 establecer-procesos-para-la-manipulacion-de-la-base-de-datos
PDF
Clave foránea
PDF
Operaciones basicas de sql
PPTX
Excel 2007 informatica i i
DOCX
PDF
8. formulas y funciones excel
DOCX
Slideshare 0 examen michelle espinosa
4 to referencia relativa
4 establecer-procesos-para-la-manipulacion-de-la-base-de-datos
Clave foránea
Operaciones basicas de sql
Excel 2007 informatica i i
8. formulas y funciones excel
Slideshare 0 examen michelle espinosa

La actualidad más candente (17)

PPTX
Consultas sql
PDF
Sesion 1
DOCX
Contenido científic2 OPERADORES Y REFERENCIAS DE CELDAS
PPTX
DOCX
Funcioes de excel
DOCX
PDF
Alumno valoracion 1.2 de programacion
PPTX
Empleo de base de datos
PDF
Objeto De Aprendizaje
PPTX
Grupo alfa 3
PDF
Normalizacion
PPTX
Referencias - Excel 2013
PPTX
DML3.pptx
PDF
Referencia de celdas
PPTX
14 structure query language
Consultas sql
Sesion 1
Contenido científic2 OPERADORES Y REFERENCIAS DE CELDAS
Funcioes de excel
Alumno valoracion 1.2 de programacion
Empleo de base de datos
Objeto De Aprendizaje
Grupo alfa 3
Normalizacion
Referencias - Excel 2013
DML3.pptx
Referencia de celdas
14 structure query language
Publicidad

Similar a Guía de declaraciones de open sql (20)

DOCX
SENTENCIAS DE SQL SERVER
PDF
Consultas basicas en sql server
PPTX
PDF
Consultas básicas en sql server
PDF
Sql y programacion en access 2010
PPTX
Sistemas de infordsvljnkdsjncmación.pptx
DOC
Sql comamdo
PPTX
Sistemas de infshdaiusahofijhdsiuhformación.pptx
DOC
Proyecto De Aplicacion A La Bases Datos
PPT
Tutorial - Introducción a MySQL (pt 1).ppt
DOCX
Introdução a abap
PPT
BD_L8_EXP_ROZIC_CAP9_SQL
DOCX
Tutorial SQL
PPTX
Consultas sql 2014
PPTX
Consultas sql 2014
PPTX
Lenguaje transact sql
DOCX
2. creación de tablas 2007
DOC
Sentencias Sql
DOC
Trabajando con sql (parte 1)
SENTENCIAS DE SQL SERVER
Consultas basicas en sql server
Consultas básicas en sql server
Sql y programacion en access 2010
Sistemas de infordsvljnkdsjncmación.pptx
Sql comamdo
Sistemas de infshdaiusahofijhdsiuhformación.pptx
Proyecto De Aplicacion A La Bases Datos
Tutorial - Introducción a MySQL (pt 1).ppt
Introdução a abap
BD_L8_EXP_ROZIC_CAP9_SQL
Tutorial SQL
Consultas sql 2014
Consultas sql 2014
Lenguaje transact sql
2. creación de tablas 2007
Sentencias Sql
Trabajando con sql (parte 1)
Publicidad

Último (11)

PPTX
Presentación de un estudio de empresa pp
PPTX
Guia de power bi de cero a avanzado detallado
PDF
Herramientaa de google google keep, maps.pdf
PPT
laser seguridad a la salud humana de piel y vision en laser clase 4
PDF
Mesopotamia y Egipto.pptx.pdf historia universal
PPTX
tema-2-interes-.pptx44444444444444444444
PDF
Frases de Fidel Castro. Compilación Norelys Morales Aguilera
PPTX
presentacion_energias_renovables_renovable_.pptx
PDF
CAPACITACIÓN MIPIG - MODELO INTEGRADO DE PLANEACIÓN Y GESTIÓN
PDF
[Ebook gratuito] Introducción a la IA Generativa, Instalación y Configuración...
PPTX
FUNCIONES DE CLASSROOM EN EL FUNCIONAMIENTO ESCOLAR
Presentación de un estudio de empresa pp
Guia de power bi de cero a avanzado detallado
Herramientaa de google google keep, maps.pdf
laser seguridad a la salud humana de piel y vision en laser clase 4
Mesopotamia y Egipto.pptx.pdf historia universal
tema-2-interes-.pptx44444444444444444444
Frases de Fidel Castro. Compilación Norelys Morales Aguilera
presentacion_energias_renovables_renovable_.pptx
CAPACITACIÓN MIPIG - MODELO INTEGRADO DE PLANEACIÓN Y GESTIÓN
[Ebook gratuito] Introducción a la IA Generativa, Instalación y Configuración...
FUNCIONES DE CLASSROOM EN EL FUNCIONAMIENTO ESCOLAR

Guía de declaraciones de open sql

  • 1. Una guía completa para las declaraciones de OpenSQL: tutorial paso a paso con capturas de pantalla En mi primera publicación de blog sobre SCN, me gustaría dar una descripción general de la sintaxis de consulta de OpenSQL. A partir de la declaración SELECT más simple, me gustaría demostrar todos los elementos del lenguaje de OpenSQL, construyendo gradualmente una consulta de base de datos muy compleja. Para cada paso, proporcionaré un ejemplo empresarial y una captura de pantalla para que pueda ver el resultado de cada consulta SELECT. He utilizado la base de datos de demostración de vuelo disponible en todos los sistemas SAP, por lo que puede probar las consultas por sí mismo. Nota: en esta publicación no discutiré temas relacionados con el desempeño en detalle. Eso haría que esta publicación fuera demasiado larga. Quizás en una publicación futura ¡Vamos a empezar! Select Ejemplo 1: la declaración SELECT más simple Hay tres partes obligatorias de una instrucción SELECT, que básicamente definen qué desea leer de qué tabla y dónde colocar el resultado: 1. Después de la palabra clave SELECT, debemos especificar los campos del llamado "conjunto de resultados" ("conjunto de resultados" en la ayuda de SAP). Aquí definimos qué campos queremos ver en el resultado de la selección. En el Ejemplo 1, ingresamos “*”, un carácter especial que significa que se devolverán todos los campos de las tablas definidas. Esta es una característica útil, pero tenga en cuenta que, si selecciona todos los campos de una tabla que consta de 250 columnas y usa solo cinco de ellas, eso desperdicia una gran cantidad de recursos de CPU, memoria y red. En este caso, es
  • 2. mejor enumerar los cinco campos explícitamente (especialmente si selecciona muchos registros). 2, la cláusula FROM define de qué tabla (s) leer los datos. Aquí debe especificar al menos una tabla o vista que exista en el Diccionario de datos. En el primer ejemplo solo accederemos a una tabla, y los ejemplos posteriores usarán más tablas. 3, La cláusula INTO define dónde colocar los resultados, lo que generalmente se denomina “área de trabajo”. Aquí debe definir el objeto de datos que contendrá el conjunto de resultados utilizando una de las siguientes opciones: - INTO x, donde x es una estructura. - INTO TABLE y, donde y es una tabla interna. - APENDIENDO LA TABLA z, donde z es una tabla interna. En esto, el conjunto de resultados se agrega a la tabla interna (sin borrar el contenido existente). - INTO (a, b, c,…), donde a, b, c, etc.son variables con tipos elementales Hay varias instrucciones en la ayuda de SAP con respecto a los requisitos previos de las áreas de trabajo (tipo de datos, etc.) y las reglas de asignación (conversiones automáticas, etc.) que no quiero copiar y pegar aquí. De todos modos, recomendaría usar una estructura idéntica a la selección de campo o usar la adición "CAMPOS DE CORRESPONDIENTE". Esto asignará los campos seleccionados a los campos del área de trabajo según el nombre del campo (no de izquierda a derecha). Para todas las construcciones excepto INTO TABLE, si el conjunto de resultados está vacío, el objetivo permanece sin cambios. Sugerencia: la cláusula INTO se puede omitir en un caso especial, cuando usa una función de grupo para contar el número de líneas que coinciden con la cláusula WHERE. En este caso, la variable de sistema SY-DBCNT contendrá el número de registros encontrados. Vea el ejemplo 5.
  • 3. Nota: Falta la cláusula INTO en las capturas de pantalla porque la herramienta que he usado la genera automáticamente. De todos modos, todos los ejemplos usarían la variante INTO TABLE para buscar todos los registros coincidentes a la vez. Requisito comercial: queremos seleccionar todos los datos para 100 reservas de la tabla de reservas. Realmente simple, ¿verdad? ¿Cómo lograrlo? Simplemente defina "*" después de la palabra clave SELECT, especifique la tabla SBOOK en la cláusula FROM y limite el número de registros obtenidos mediante la cláusula "UP TO N ROWS". Esto se puede usar para definir el número máximo de líneas que queremos que devuelva la consulta. Esto se usa generalmente para verificaciones de existencia (HASTA 1 FILA), pero en este ejemplo hemos limitado la consulta para que devuelva un máximo de 100 registros. A menos que especifique la cláusula ORDER BY, esto devolverá 100 registros arbitrarios, por lo que no puede saber qué 100 devolverá. Captura de pantalla 1: Simplemente seleccione 100 reservas de la mesa SBOOK
  • 4. Where Ejemplo 2: agregar una cláusula WHERE y una combinación de tabla La cláusula WHERE Por lo general, las instrucciones SELECT no leen todo el contenido de una tabla (las excepciones típicas son pequeñas tablas de personalización que contienen algunos registros), sino que devuelven solo entradas específicas. La cláusula WHERE se usa para filtrar el conjunto de resultados, o en otras palabras, decirle a la base de datos qué registros recuperar. Aquí define una expresión lógica que la base de datos evaluará para cada fila de la base de datos. Requisito comercial: devolver solo las reservas de Lufthansa (el campo CARRID debe contener “LH”) y las reservas canceladas no son necesarias (CANCELADO debe ser igual al espacio). La base de datos evaluará esta condición para cada registro de la tabla y, si la condición es verdadera, se colocará en el conjunto de resultados. Puede escribir condiciones lógicas mucho más complejas como veremos en los siguientes ejemplos. Se puede vincular cualquier número de expresiones lógicas a una expresión lógica usando palabras clave AND u OR y el resultado de una expresión lógica se puede negar usando la palabra clave NOT. Tenga en cuenta el orden de evaluación (asegúrese de utilizar correctamente los paréntesis). Los operadores simples que se utilizan para comparar valores de campo son EQ, NE, GT, LT, GE y LE (equivalente a =, <>,>, <,> =, <=). La tabla se une La segunda adición interesante en este ejemplo es la combinación de tablas. A menudo, los datos necesarios para un proceso empresarial específico se almacenan en varias tablas. Aunque podría ser una opción seleccionar datos de cada tabla usando comandos SELECT separados y combinar los resultados usando código ABAP ejecutado en el servidor de aplicaciones, muchas veces es más conveniente y eficaz usar solo una instrucción SELECT para leer todas las tablas a la vez.
  • 5. Requisito comercial. leer los datos del cliente de la tabla SCUSTOM para el cliente de cada reserva. Esto se logra mediante la denominada "unión de tabla": una construcción que indica a la base de datos que acceda a una tabla adicional en función de una condición. Esta llamada "condición de combinación" (o "expresión de combinación") representa el vínculo lógico entre las dos tablas. En este ejemplo es el número de cliente: para cada reserva en la tabla SBOOK, la base de datos buscará los datos del cliente en la tabla SCUSTOM basándose en el número de cliente. Debido a que usamos "*" para definir los campos del conjunto de resultados y leemos de dos tablas en este ejemplo, el conjunto de resultados contiene todos los campos de ambas tablas. Si hay un campo con el mismo nombre en ambas tablas, solo se devolverá uno (el de la última tabla en la cláusula FROM; cada combinación sobrescribe el contenido del campo). Nota: la herramienta que he usado para las capturas de pantalla genera automáticamente un campo separado en este caso. Esta es la razón por la que puede ver campos duplicados. La sintaxis de una condición de unión es casi la misma que en una cláusula WHERE con algunas diferencias notables que no quiero copiar y pegar aquí desde la Ayuda de SAP (no puedo usar subconsultas, debo usar AND para vincular expresiones lógicas, etc.). Hay dos tipos de combinaciones de tablas en OpenSQL: combinaciones internas y combinaciones externas. Discutiremos la diferencia en el siguiente ejemplo. Sugerencia: las sentencias SELECT que utilizan combinaciones de tablas omiten el almacenamiento en búfer de SAP.
  • 6. Captura de pantalla 2: agregar una cláusula WHERE y una combinación de tabla Ejemplo 3: agregar datos de otras dos tablas Afortunadamente, OpenSQL permite unir varias tablas a la vez: se pueden unir un máximo de 25 tablas en una instrucción SELECT. Aquí, en este ejemplo, agregamos datos de dos tablas más: T005T que contiene datos de países y GEOT005S que contiene información geográfica de regiones. Requisito comercial: muestre el nombre del país en lugar del código del país y muestre la latitud y la longitud de la región del cliente. Una cosa especial en este ejemplo es la condición de combinación de la tabla T005T. Esta tabla depende del idioma, por lo que se necesita una clave de idioma para obtener la descripción textual de un país en un idioma específico. Recuerde: la condición de unión le dice a la base de datos cómo obtener un registro de la tabla B basado en un registro de la tabla A (A es el lado izquierdo y B es la tabla del lado derecho). Esto es especial ahora porque usamos el idioma de inicio de sesión del usuario actual del campo SY-LANGU. Todos los campos de la estructura SY se pueden utilizar en las condiciones de unión (fecha actual, hora, ID del sistema, etc.) así como en las cláusulas WHERE y HAVING.
  • 7. ¿Qué pasaría si omitiéramos la especificación de la clave del idioma? La base de datos devolvería varias filas con la misma información de reserva, cliente y región. ¿Por qué? Simplemente porque hay más de una entrada en la tabla T005T para el mismo país. Digamos que tenemos dos entradas para el país 'DE': es 'Deutschland' en alemán y es 'Alemania' en inglés. En el caso de un cliente alemán, el motor de la base de datos evaluaría la condición de unión (T005T-LAND1 = SCUSTOM-COUNTRY) para ambos registros, y ambos serían verdaderos, por lo que se devolverían dos filas: una con texto en inglés y otra con texto en alemán . Captura de pantalla 3: combinaciones de varias tablas. Observe que todas las líneas contienen una latitud y una longitud. Ejemplo 4: Otro tipo de combinación de tabla: combinación externa izquierda Aquí viene la diferencia entre los dos tipos de combinaciones de tablas en OpenSQL: la combinación interna y la combinación externa (por ejemplo, "SELECCIONAR * DE UNA JUNTA INTERNA B" / "SELECCIONAR * DE UNA JUNTA EXTERIOR IZQUIERDA B").
  • 8. Básicamente, la diferencia es el comportamiento en caso de que no haya una entrada correspondiente en la tabla B para un registro en la tabla A. En caso de una combinación interna, no se colocaría ningún registro en el conjunto de resultados. En el caso de una combinación externa izquierda, habría un registro en el conjunto de resultados, pero todos los campos provenientes de la tabla B estarían vacíos. Este comportamiento es muy fácil de ver en este ejemplo: agregamos coordenadas geográficas a nuestra consulta en el ejemplo anterior usando una combinación interna. La tabla GEOT005S contiene coordenadas para las regiones del país. Siempre que no se encontró un registro en la tabla GEOT005S para la región de un cliente, toda la línea se eliminó del conjunto de resultados. Es por eso es que solo puede ver clientes con latitud y longitud que no estén vacías. En el ejemplo actual, agregamos la latitud y la longitud de la región del cliente utilizando una combinación externa izquierda. Como puede ver en la captura de pantalla, solo hay un cliente para el que se devuelven las coordenadas. Para todos los demás registros, la base de datos no encontró un registro adecuado en GEOT005S, por lo que las coordenadas están vacías. Si se accede a GEOT005S mediante INNER JOIN, estos registros se excluirán del conjunto de resultados. Captura de pantalla 4: combinación de tabla mediante una combinación externa izquierda. Observe que ahora los clientes con latitud y longitud vacías aparecen en la lista.
  • 9. Nota: si ha revisado cuidadosamente la captura de pantalla podría notar que hay un cliente con una región definida ('IL') pero no se muestran coordenadas. La razón podría ser que no hay una entrada en GEOT005S para la región 'IL' del país 'EE. UU.', Pero no es el caso. De alguna manera, la base de datos de demostración de vuelo estándar contiene entradas incorrectas que tienen un espacio innecesario. Esta es la razón por la que la base de datos no encuentra el registro coincidente, ya que 'IL' <> 'IL'. Captura de pantalla 4 b: entradas incorrectas para la región 'IL' en la tabla GEOT005S Corregí estas entradas usando esta simple declaración de actualización: Después de corregir las entradas en la tabla SCUSTOM, la consulta completa las coordenadas para todos los clientes en la región 'IL':
  • 10. Captura de pantalla 4 c: combinación de tabla usando una combinación externa izquierda después de corregir las entradas problemáticas de la base de datos.Observe que ahora todos los clientes que tienen una región definida tienen las coordenadas completadas. Ejemplo 5: agregar una función de grupo simple Muchas veces, la empresa no está interesada en todos los registros de datos individuales, pero desea ver una agregación basada en un campo específico. Por ejemplo, la suma de todas las ventas por vendedor, costos por proyecto, etc. En este caso tenemos dos opciones: recuperar todos los registros relevantes de la base de datos y realizar los cálculos en el servidor de aplicaciones usando nuestro propio código ABAP, o realizar el cálculo utilizando el motor de base de datos. Requisito comercial: queremos ver el número de reservas que coinciden con nuestros criterios de selección. (reservas de Lufthansa que no se cancelen). Para lograr esto usando la base de datos, tenemos que agregar una cláusula GROUP BY y tenemos que definir la función agregada (también llamada como función de grupo) COUNT en la cláusula SELECT.
  • 11. Group by La cláusula GROUP BY combina grupos de filas en el conjunto de resultados en una sola fila. En este caso muy simple, queremos ver el número total de reservas, no desglosado por ningún otro campo. La función COUNT (*) determina el número de filas en el conjunto de resultados o en el grupo actual. En este momento no tenemos ningún grupo definido, por lo que en nuestro caso devuelve el número total de reservas. Captura de pantalla 5: una función de grupo simple que cuenta el número de reservas que coinciden con los criterios de selección. Nota: La función COUNT también se puede utilizar para determinar el número de valores diferentes de un campo específico en el conjunto de resultados. En este caso, simplemente ponga el nombre del campo entre paréntesis y agregue la palabra clave DISTINCT. Por ej. para contar de cuántos países son los clientes, use "COUNT (DISTINCT country)" en la cláusula SELECT. Es importante tener en cuenta que las funciones de grupo siempre se realizan después de la evaluación de la cláusula WHERE. El motor de la base de datos primero lee los
  • 12. registros que coinciden con la cláusula WHERE, luego forma grupos (vea el siguiente ejemplo) y luego realiza la función de grupo. El uso de la cláusula GROUP BY y las funciones agregadas asegura que los agregados y grupos sean ensamblados por el sistema de base de datos, no por el servidor de aplicaciones. Esto puede reducir considerablemente el volumen de datos que deben transferirse desde la base de datos al servidor de aplicaciones. Por otro lado, por supuesto, esto necesita más recursos de la base de datos. Sugerencia: Con el uso de GROUP BY, la instrucción SELECT evita el almacenamiento en búfer de SAP. Ejemplo 6: definir grupos para las funciones de grupo Hemos aprendido que las funciones de grupo realizan ciertos cálculos en grupos de registros de bases de datos. Si no especificamos explícitamente un grupo, entonces todos los registros en el conjunto de resultados se consideran como un gran grupo, como en el ejemplo anterior. Requisito comercial: mostrar el número de reservas (no canceladas de Lufthansa) por cliente. En este caso, formamos grupos de registros de base de datos basados en el número de cliente enumerando el ID de campo en la cláusula group by. Además, tenemos que ingresar el campo ID de la tabla SCUSTOM en la cláusula SELECT antes de la función de grupo.
  • 13. Captura de pantalla 6: Agrupación de filas por ID de cliente. La función de grupo COUNT se realiza en cada grupo para contar el número de reservas de cada cliente. Como puede ver, ahora el motor de base de datos devuelve tantos registros como ID de cliente tengamos en el conjunto de resultados y el número de reservas relevantes junto a ellos. Exactamente lo que queríamos. Nota: en todos nuestros ejemplos anteriores, usamos el signo "*" en la cláusula SELECT (lista de campos). Sin embargo, aquí tenemos que definir explícitamente los campos necesarios para crear grupos de registros. Es obligatorio agregar el nombre de la tabla y el signo ~ antes del nombre de un campo de la base de datos, si más de una tabla tiene un campo con el mismo nombre. Ejemplo 7: agregar información adicional Requisito comercial: mostrar campos adicionales en la lista de resultados (nombre, ciudad, país, código de región, coordenadas). ¿Cómo hacerlo? Simplemente agréguelos a la cláusula SELECT después del número de cliente antes de la función COUNT. Tenga en cuenta que también debe agregar el
  • 14. campo a la cláusula GROUP BY, de lo contrario, encontrará un error de sintaxis. Los campos que usa para formar grupos deben estar en la cláusula SELECT, y nada más debe estar en la cláusula SELECT que no esté en la cláusula GROUP BY a menos que sea un argumento de una función de grupo. Captura de pantalla 6a: se muestran campos adicionales en la lista. Nota: Es técnicamente posible omitir un campo de la cláusula SELECT, que es parte de la cláusula GROUP BY, pero realmente no tiene mucho sentido. Por ejemplo, el conjunto de resultados se agrupará en dos campos, pero solo se mostrará un campo de agrupación.
  • 15. Captura de pantalla 6b: omitir el campo ID de conexión de la cláusula SELECT es sintácticamente correcto, sin embargo, no tiene sentido. Observe que el mismo ID de operador aparece tantas veces como los ID de conexión existen para él, pero los ID de conexión no forman parte del conjunto de resultados. Nota: Ahora podrías preguntarte que en el ejemplo anterior te dije que agregando campos antes de la función de grupo es como definimos grupos, pero aquí el número de reservas no cambió. La razón es que hemos agregado campos de tablas que tienen una relación 1: 1 con el cliente. Un cliente tiene un solo nombre, una ciudad está en un país y región y tiene un par de coordenadas. Si hubiéramos optado por agregar el campo Clase de vuelo (Primera clase / Business / Economy), entonces el conjunto de
  • 16. resultados podría contener más de una línea por cliente: tantas líneas por cliente como tantos tipos de vuelos haya tenido. Veremos cómo funciona esto en el ejemplo 15. Ejemplo 8: Definición del orden de los registros en el conjunto de resultados Puede utilizar la cláusula ORDER BY en una consulta para definir el orden de clasificación de los registros devueltos. Simplemente enumere todos los campos que desea utilizar como criterio de clasificación. Puede utilizar las palabras clave ASCENDING y DESCENDING para cada campo para especificar el modo de clasificación (ASCENDING es el valor predeterminado, por lo que se puede omitir). Requisito comercial: mostrar los clientes con más reservas. ¿Qué hacemos ahora? Ordenamos la lista por el resultado de la función COUNT en orden descendente y luego por el nombre del cliente. Captura de pantalla 7: el conjunto de resultados se ordena mediante la cláusula ORDER BY.
  • 17. Como puede ver, hay varios clientes que tienen más de diez reservas (no canceladas, Lufthansa). Nota: Si todos los campos clave están en la lista de campos y se especifica una única tabla de base de datos después de FROM (no una vista o expresión de combinación), la adición PRIMARY KEY se puede usar para ordenar el conjunto de resultados en orden ascendente según la clave primaria de la mesa. Ejemplo 9: filtrado basado en una función de grupo Requisito comercial: el jefe solo está interesado en los clientes que tienen más de diez reservas de Lufthansa no canceladas. ¿Cómo hacemos esto? Supongo que la primera idea sería agregar una nueva condición a la cláusula WHERE para filtrar registros donde la función COUNT es mayor que diez. Sin embargo, esto no funcionará debido al lenguaje OpenSQL (y SQL en general). La razón es que la cláusula WHERE filtra los registros de la base de datos antes de que el motor de la base de datos cree los grupos. Una vez creados los grupos, se calculan las funciones de grupo y se crea el conjunto de resultados. La cláusula WHERE no se puede utilizar para filtrar en función de los resultados de la función de grupo. En casos como estos, se debe utilizar la cláusula HAVING. Esto es similar a la cláusula WHERE, pero la diferencia es que se evalúa después de que se crean los grupos y se realizan las funciones de grupo. En pocas palabras: para filtrar en función del resultado de las funciones de grupo, se debe usar la cláusula HAVING (también llamada condición de grupo).
  • 18. Captura de pantalla 8: uso de la cláusula HAVING para filtrar el conjunto de resultados en función de las funciones de grupo. Como puede ver en la captura de pantalla, ahora solo se devuelven 23 registros, aunque hemos permitido tener 100 registros mediante el uso de la adición HASTA N FILAS. Esto significa que hay 23 clientes que tienen más de diez reservas de Lufthansa no canceladas. Nota: Si no especifica ningún grupo usando la cláusula GROUP BY, la cláusula HAVING considerará el conjunto de resultados completo agrupado en una línea. Para un ejemplo rápido, suponga que tenemos 10 registros en la tabla SCARR. La consulta "SELECT COUNT (*) FROM scarr HAVING count (*) GT 0" devolverá una sola línea con el número de registros en la tabla, pero la consulta "SELECT COUNT (*) FROM scarr HAVING count (*) GT 10” No devolverá ninguna línea (conjunto de resultados vacío). Subconsultas Ejemplo 10: uso de subconsultas
  • 19. La posibilidad de combinar varias sentencias SELECT en una es una característica muy útil en OpenSQL. Esto se usa principalmente cuando no conoce exactamente los criterios de filtro durante el tiempo de diseño o cuando tiene que usar una comparación con un valor calculado dinámicamente. Requisito comercial: la lista debe incluir solo a los clientes que nunca hayan cancelado un vuelo (cualquier aerolínea, no solo Lufthansa). A primera vista, lógicamente podría preguntar que esto ya está hecho, ya que hemos "cancelado el espacio de EQ" en nuestra cláusula WHERE. Esto no es correcto, porque esto solo influye en nuestra función de grupo, por lo que solo se cuentan las reservas no canceladas. Esto significa que, si un cliente tiene 20 reservas con una cancelada, estará en nuestra lista con 19 reservas. De acuerdo con nuestro requisito, no queremos que este cliente esté en nuestra lista, entonces, ¿cómo lo logramos? Una manera fácil de resolver esto es agregar una subconsulta a nuestra cláusula WHERE que verifica si hay una reserva cancelada para el cliente. Subconsultas en general Básicamente, una subconsulta es una instrucción SELECT entre paréntesis que se usa en una expresión lógica. No es necesario tener una cláusula INTO porque el motor de la base de datos procesará el resultado de la subconsulta. ¿Cómo se evalúan los resultados de las subconsultas? Esto depende de si la subconsulta está correlacionada o no. Si una subconsulta usa campos de la instrucción SELECT circundante en su condición WHERE, se denomina subconsulta correlacionada. En este caso, el resultado de la subconsulta se evaluará para cada línea en el conjunto de resultados de la instrucción SELECT circundante (en cuya cláusula WHERE se coloca la subconsulta). Esto implica que la subconsulta es para cada registro en el conjunto de resultados de la instrucción SELECT circundante. Por otro lado, una subconsulta sin ninguna referencia a la instrucción SELECT circundante se ejecuta solo una vez. Hay diferentes operadores que se pueden usar con subconsultas, usaremos el operador "EXISTS" (negado) en este ejemplo. Discutiré los demás en el Ejemplo 13.
  • 20. Las subconsultas se pueden anidar, lo que significa que puede poner una subconsulta en la cláusula WHERE de una subconsulta. Veremos un ejemplo de esto más adelante en el Ejemplo 13. Ahora, tome el ejemplo actual: necesitamos verificar si un cliente tiene una reserva cancelada, por lo que tenemos que crear una relación entre el ID de cliente en el conjunto de resultados de nuestra declaración SELECT externa y la subconsulta (por lo que usamos una subconsulta correlacionada). Esto se hace agregando una condición a la cláusula WHERE de la subconsulta para que coincida con los ID de cliente. Captura de pantalla 9: uso de una subconsulta. Como puede ver, ahora solo se devuelven 20 registros, por lo que tres clientes tuvieron un vuelo cancelado en nuestra lista anterior. Alias Alias de tabla Observe que aquí debemos usar los llamados "alias de tabla" porque seleccionamos de la misma tabla tanto en la consulta circundante como en la subconsulta. Esto significa que de alguna manera debemos definir explícitamente el nombre de la tabla para los campos que se compararán, de lo contrario, el motor de la base de datos no sabría a qué campo de la tabla nos referimos. Esto se hace con el uso de alias de tablas. Básicamente, puede dar un nombre a sus tablas y hacer referencia a ellas utilizando el alias. Aquí definí "sq" como un alias para la subconsulta. Debe utilizar el
  • 21. carácter ~ entre el alias de la tabla y el nombre del campo (y, por supuesto, entre el nombre de la tabla y el nombre del campo como en los ejemplos anteriores). Notas: • Las subconsultas no se pueden utilizar al acceder a las mesas de billar o las mesas de grupo. • la cláusula ORDER BY no se puede utilizar en una subconsulta. • Si se utiliza una subconsulta, la instrucción Open SQL omite el almacenamiento en búfer de SAP. Nota: las subconsultas también se pueden usar en la cláusula HAVING como se ve en el ejemplo 14. Sugerencia: podríamos haber resuelto el requisito sin una subconsulta correlacionada. En este caso, la subconsulta seleccionaría a todos los clientes que tenían una reserva cancelada, y la declaración SELECT circundante verificaría a cada cliente si está en el conjunto de resultados de la subconsulta: Ejemplo simplificado: SELECT ... WHERE customid NOT IN (seleccione customid del sbook donde se canceló EQ 'X'). es igual a SELECT ... WHERE no existe (seleccione bookid de sbook como sq donde sq ~ customid EQ sbook ~ customid y EQ cancelado 'X') Ejemplo 11: operadores especiales En todos los ejemplos anteriores solo hemos utilizado el operador 'EQ' (igual que '=') y el 'GT' (> =) para comparar valores de campo. Sin embargo, también hay otros más complejos. ENTRE Este operador es muy simple, es básicamente “<=” y “> =” juntos. Requisito comercial: excluir de nuestra lista solo a los clientes que tengan reservas canceladas en el primer trimestre de 2005. La sintaxis para esto es “campo ENTRE valor1 Y valor2”. Sugerencia: desde la perspectiva comercial, esperamos más clientes en el conjunto de resultados, ya que excluimos menos clientes debido a una subconsulta más restrictiva.
  • 22. Captura de pantalla 10: uso del operador BETWEEN. Como puede ver, hay 21 clientes en nuestra lista, por lo que hay un cliente que aparece nuevamente (tuvo cancelación antes o después del primer trimestre de 2005). IGUAL QUE Esta expresión es una herramienta muy flexible para las comparaciones de cadenas de caracteres basadas en un patrón. El patrón se puede definir utilizando caracteres comodín: "%" representa cualquier cadena de caracteres (incluso una vacía) y "_" representa cualquier carácter individual. La expresión LIKE distingue entre mayúsculas y minúsculas y los caracteres en blanco al final del patrón se ignoran (LIKE '__' es igual a LIKE '__'). Requisito comercial (bastante extraño ...): restringir aún más nuestra lista para que solo contenga clientes con un nombre que comience con "A". Agregamos “nombre LIKE 'A%'” a la cláusula WHERE para lograr esto.
  • 23. Captura de pantalla 11: uso del operador LIKE para filtrar la lista según el nombre del cliente. Nota: ¿Qué hacer si queremos buscar registros que contengan '_' en un campo específico? Dado que este es un símbolo reservado, tenemos que usar la adición ESCAPE, que permite definir un carácter de escape. Este carácter de escape cancela las funciones especiales de los caracteres comodín (simplemente coloque el carácter de escape antes del carácter comodín que se va a cancelar). Un ejemplo rápido: seleccione todos los números de material que contienen un guión bajo: Enfoque incorrecto (devuelve todos los números de material):SELECT matnr FROM mara donde matnr LIKE '% _%' Buen enfoque: SELECCIONE matnr FROM mara donde matnr LIKE '% ~ _%' ESCAPE '~' Sugerencia no es posible especificar un campo de tabla como patrón. Requisito comercial (aún más extraño): ahora solo queremos ver a los clientes con un nombre que comience con 'A' y que tenga la 'd' como tercera letra.
  • 24. Captura de pantalla 12: uso del operador LIKE con los dos caracteres especiales “%” y “_”. Como puede ver, todavía tenemos tres clientes que cumplen con todos nuestros criterios de selección. EN Este operador le permite comparar un campo con un conjunto de valores fijos. Esto es útil ya que puede reemplazar una expresión más larga y mucho menos legible: “Field IN ('01, '03, '05')” es igual al mucho más largo “field EQ '01' o field EQ '02' o field EQ '03'” Requisito comercial: extender nuestra selección a los clientes de American Airlines y United Airlines también.
  • 25. Captura de pantalla 13: uso del operador IN para contar las reservas de otras aerolíneas también. Como era de esperar, ahora tenemos muchos más clientes que cumplen con los criterios de selección menos restrictivos. Nota: el operador IN también se puede utilizar con una tabla de selección, como se ve en el capítulo 17. Ejemplo 12: Otras funciones de grupo Hasta ahora, solo hemos utilizado la función de grupo COUNT para contar el número de reservas que coinciden con nuestros criterios de selección. Hay un total de cinco funciones de grupo disponibles en OpenSQL. Los cuatro restantes que aún no hemos visto son todos cálculos matemáticos: SUM, MIN, MAX y AVG que calculan el total, mínimo, máximo y promedio de un campo respectivamente. Existen algunas restricciones relacionadas con el uso de funciones de grupo: • Si la adición PARA TODAS LAS ENTRADAS se usa delante de WHERE, o si las tablas de grupo o agrupaciones se enumeran después de FROM, no se pueden usar otras expresiones agregadas además de COUNT (*). • Las columnas del tipo STRING o RAWSTRING no se pueden utilizar con funciones agregadas. • Los valores nulos no se incluyen en el cálculo de las funciones agregadas. El resultado es un valor nulo solo si todas las filas de la columna en cuestión contienen el valor nulo.
  • 26. Requisito comercial: el jefe quiere ver el precio total, promedio, mínimo y máximo de la reserva para cada cliente (en la moneda de la aerolínea). Captura de pantalla 14: uso de todas las funciones de grupo (MIN, MAX, SUM, AVG, COUNT). Nota: al igual que con la función COUNT, la palabra clave DISTINCT se puede usar para realizar la función de grupo solo en valores distintos (por lo que el resultado de SUM (DISTINCT A) para dos registros que tienen el valor 10 en un campo A sería 10). Nota: el tipo de datos para AVG y SUM debe ser numérico. El tipo de datos MIN, MAX y SUM es el tipo de datos del campo de tabla correspondiente en el Diccionario ABAP. Las expresiones agregadas con la función AVG tienen el tipo de datos FLTP y las que tienen COUNT tienen el tipo de datos INT4. Sugerencia: la herramienta que he usado para la demostración reemplaza los tipos de campo de estas funciones agregadas para una visualización más fácil de usar (en lugar de la notación exponencial). Ejemplo 13: subconsultas anidadas
  • 27. Las subconsultas se pueden anidar, lo que significa que puede poner una subconsulta en la cláusula WHERE de una subconsulta. Se permite un máximo de diez sentencias SELECT dentro de una consulta de OpenSQL (una sentencia SELECT puede tener un máximo de nueve subconsultas). Requisito comercial: excluir solo a los clientes que hayan cancelado reservas en el primer trimestre de 2005 y el idioma de la agencia de viajes es el inglés, donde se realizó la cancelación. Bastante incómodo, pero tenía que averiguar algo Podemos implementar esta lógica usando una subconsulta anidada: agregamos este criterio a la cláusula WHERE de la subconsulta externa (seleccione todos los números de agencia donde el idioma es el inglés). Esto es diferente de nuestra subconsulta anterior, debido a la palabra clave que usamos para evaluarla. Expresiones lógicas para subconsultas - EXISTS: esto es lo que hemos usado en nuestra primera subconsulta. Esto devuelve VERDADERO si la subconsulta devuelve algún registro (uno o más) en su conjunto de resultados; de lo contrario, devuelve FALSO. - EQ, GT, GE, LT, LE: estos operadores se pueden utilizar para comparar un campo con el resultado de la subconsulta. Si la subconsulta devuelve más de una fila, obviamente el motor de la base de datos no sabrá cuál usar para la comparación: se producirá una excepción no detectable. - Para utilizar subconsultas que devuelven varias filas, debe utilizar el operador IN (comprueba si el campo es igual a alguno de los valores devueltos por la subconsulta) o una de las palabras clave ALL, ANY y SOME junto con EQ, GT, GE, LT o LE. Estos influirán en la comparación de una manera bastante autoexplicativa: la comparación se llevará a cabo con todos los registros devueltos por la subconsulta, y la comparación devolverá VERDADERO si todos (TODOS) o al menos uno (CUALQUIER, ALGUNOS) registros regresan VERDADERO para la comparación. No hay diferencia entre las palabras clave ALGUNAS y CUALQUIER.
  • 28. ¿Qué resultado esperamos? Dado que nuestra subconsulta externa se usa para filtrar clientes con reservas canceladas, una subconsulta menos restrictiva (lograda por la subconsulta anidada) significaría más clientes en nuestra lista. Prácticamente: cuantas menos agencias incluyamos en nuestra búsqueda de cancelaciones, más clientes obtenemos en la lista. Captura de pantalla 15: anidación de subconsultas. Como puede ver, en realidad tenemos un cliente más en nuestra lista, que canceló su reserva en una agencia donde el idioma no es el inglés. Ejemplo 14: HAVING y GROUP BY en una subconsulta Requisito comercial: excluir únicamente a los clientes que tengan al menos tres cancelaciones (vuelo de Lufthansa en el primer trimestre de 2005 en una agencia de habla inglesa). Como tenemos que contar el número de estas reservas, tenemos que utilizar la función de grupo COUNT y agrupar las reservas por ID de cliente. De esta forma obtenemos el número de reservas coincidentes por cliente. Luego, simplemente agregamos la cláusula HAVING para asegurarnos de que solo excluimos de nuestra consulta principal a los clientes que tienen más de dos cancelaciones.
  • 29. Podemos esperar tener más clientes en nuestro conjunto de resultados, ya que tenemos una subconsulta más restrictiva que usamos para filtrar los clientes. Captura de pantalla 16: uso de las cláusulas GROUP BY y HAVING en una subconsulta. Como puede ver, tenemos dos clientes más en nuestra lista (que tienen una o dos reservas canceladas coincidentes). Ejemplo 15: Extendamos la cláusula GROUP BY Requisito comercial: incluya solo a los clientes que tengan más de 10 reservas para la misma aerolínea. No importa cuál, pero deberían ser más de diez. Hasta ahora hemos contado todas las reservas de los clientes que cumplen con todos nuestros criterios (por ejemplo, tener más de 10 reservas de cualquier aerolínea). Esto podría ser como si alguien tuviera 5 reservas para Lufthansa, 5 para American Airlines y 2 para United Airlines (el total es superior a 10). Ahora queremos ver algo así como 11 para Lufthansa.
  • 30. Es muy simple resolver esto agregando el código de la aerolínea (CARRID) a la lista de campos de nuestra consulta principal. Recuerde, el motor de la base de datos creará grupos de registros basados en todos los campos enumerados antes de la primera función de grupo en la lista de campos (cláusula SELECT). Si agregamos aquí el código de la aerolínea, se harán grupos por aerolínea para cada cliente y la función COUNT contará el número de reservas por cliente y aerolínea. ¿Qué cambios esperamos en nuestro conjunto de resultados? Debería haber muchos menos clientes en nuestra lista, porque deben tener más de diez reservas para la misma aerolínea. Captura de pantalla 17: agregando el ID de operador a la cláusula GROUP BY (y también a la cláusula SELECT). El resultado muestra exactamente esto: solo tenemos tres clientes (muy leales) que cumplen con nuestros criterios de selección. Tenga en cuenta que la mayor cantidad de reservas ahora es solo 12, mientras que en el ejemplo anterior era 19. Joint Ejemplo 16: Regresar a LEFT OUTER JOIN
  • 31. Para que se muestren algunas coordenadas en la lista de resultados, realizamos dos cambios: - cambiar la condición DÓNDE de la consulta principal: en lugar de comprobar el nombre del cliente y el código de la aerolínea, seleccionamos clientes de EE. UU. De esta manera tendremos muchos más clientes en nuestra lista (100 que está limitado por la adición de HASTA N FILAS) y como son de los EE. UU., Veremos algunos códigos de región para los clientes (las coordenadas se mantienen para las regiones de EE. UU.). - elimine la cláusula HAVING para incluir a los clientes con menos de 11 reservas coincidentes. Captura de pantalla 18: primer cambio: quitar el cheque para tener al menos diez reservas.
  • 32. Captura de pantalla 19: segundo cambio: seleccionar clientes de EE. UU. Ahora puede volver a ver el comportamiento de LEFT OUTER JOIN: se rellenan las coordenadas para todos los registros, donde se rellena el código de región y se encuentran las coordenadas para la región en la tabla GEOT005S. Ejemplo 17: uso de una tabla de selección en la cláusula WHERE Las tablas de selección se utilizan para definir selecciones complejas en un campo. Se utilizan principalmente junto con las pantallas de selección (utilizando la instrucción SELECT-OPTION). Cualquier selección que haga el usuario en la interfaz de usuario se convertirá en una expresión lógica compleja utilizando los operadores con los que hemos trabajado en este tutorial (EQ, GT, LE, GE, LT, NE, BETWEEN, NOT, etc.). Esta conversión la realiza el motor OpenSQL de forma automática. Para comparar los valores de un campo de tabla con una tabla de selección, debe utilizar el operador "IN".
  • 33. Requisito empresarial: solo se cuentan las reservas de clase ejecutiva y económica ('C' e 'Y') en un intervalo de tiempo complejo. Captura de pantalla 20: realización de selecciones complejas mediante tablas de selección. Observe la palabra clave "IN" utilizada como operador de comparación. Nota: la herramienta utilizada para esta demostración ofrece una interfaz de usuario para definir las tablas de selección como en las pantallas de selección. Además, la cláusula WHERE generada es visible en el lado derecho, junto a las tablas de selección R_SBOOK_FLDATE y R_SBOOK_CLASS. Ejemplo 18: La construcción "PARA TODAS LAS ENTRADAS EN" Esta construcción se usa ampliamente en ABAP y es similar a una combinación de tabla de una manera que se usa para leer datos de una tabla para registros que ya tenemos (generalmente seleccionados de otra tabla o devueltos por un módulo de función). Sin embargo, existen grandes diferencias entre los dos constructos.
  • 34. La construcción "PARA TODAS LAS ENTRADAS EN la tabla interna" le permite usar una tabla interna como base de su selección, pero no como una tabla de selección del Ejemplo 17. Si usa esta adición, puede (en realidad, debe) consultar los campos de la tabla interna en la cláusula FOR ALL ENTRIES IN para realizar la comparación con los campos de la (s) tabla (s) de la base de datos que se están leyendo. Naturalmente, los campos utilizados en la comparación deben tener tipos de datos compatibles. Como esta construcción es específica de ABAP, existe un mecanismo que traduce el comando OpenSQL a una o más declaraciones SQL nativas. En realidad, las cláusulas WHERE que se pasarán al motor de la base de datos se generarán en función del contenido de la tabla interna y la cláusula WHERE que defina. Hay varios parámetros de perfil que influyen en esta conversión, que puede verificar en la Nota SAP 48230 - Parametrización para la instrucción SELECT ... FOR ALL ENTRIES . La principal diferencia entre las uniones de tablas y esta construcción es que las uniones de tablas las realiza el servidor de base de datos y todos los datos se pasan al servidor de aplicaciones a la vez. Por otro lado, en el caso de una construcción FOR ALL ENTRIES IN, la cláusula WHERE completa se evalúa para cada fila individual de la tabla interna. El conjunto de resultados de la instrucción SELECT es la unión de los conjuntos de resultados producidos por las evaluaciones individuales. Es muy importante tener en cuenta que los registros duplicados se eliminan automáticamente del conjunto de resultados (pero en el servidor de aplicaciones y no en el servidor de la base de datos). Sintácticamente, hay una diferencia en que debe usar el signo "-" en lugar del signo "~" entre el nombre de la tabla interna y el nombre del campo de la tabla interna en la cláusula WHERE. Nota muy importante: si la tabla interna a la que se hace referencia está vacía, la cláusula WHERE completa se ignora y todas las líneas de la base de datos se colocan en el conjunto de resultados. Siempre haga una verificación en la tabla interna antes de ejecutar una consulta de selección usando esta construcción. Requisito comercial: lea la información de la aerolínea de todas las aerolíneas que aparecen en nuestra lista.
  • 35. ¿Cómo implementar esto? Ya tenemos una instrucción SELECT del ejemplo anterior, así que cree una segunda instrucción SELECT usando la construcción FOR ALL ENTRIES IN. Simplemente agregue el ID del operador como un enlace en la cláusula WHERE (similar a la condición de combinación en el caso de combinaciones de tablas) y eso es todo. Captura de pantalla 21: uso de la construcción “PARA TODAS LAS ENTRADAS EN la tabla interna”. Nota: la herramienta que he usado para la demostración usa "external_table" como el nombre de la tabla interna. El contenido proviene de la consulta de selección del ejemplo 17. Nota: A partir de la versión 6.10, se puede especificar la misma tabla interna después de FOR ALL ENTRIES y después de INTO. Sin embargo, tenga cuidado porque en este caso se borrarán todos los campos de la tabla interna que no estén llenos por la consulta SELECT. Nota: en cuanto al rendimiento, hay discusiones interminables sobre SCN si una combinación de tabla o la construcción FOR ALL ENTRIES IN es mejor. Realmente depende de la configuración de almacenamiento en búfer de las tablas que seleccione,
  • 36. los campos que use para combinaciones y selecciones, los índices que están disponibles, la cantidad de registros en ambas tablas, los parámetros de perfil del sistema SAP, etc. En general, prefiero las combinaciones ya que es una “herramienta” que está diseñada especialmente con el propósito de leer datos de múltiples tablas al mismo tiempo y se hace en la capa de la base de datos. Por supuesto, ciertas situaciones están en contra de una mesa combinada. Además, no tiene otra opción si usa un método BAPI / Módulo de función / Clase para obtener registros de la base de datos, ya que obviamente en ese caso no puede usar una combinación de tabla, pero debe usar la construcción FOR ALL ENTRIES IN. Otras palabras clave ÚNICO y PARA ACTUALIZAR Si usa la adición ÚNICA, el conjunto de resultados contendrá un registro como máximo. Si las cláusulas restantes de la instrucción SELECT devuelven más de una línea, solo se devolverá la primera. La adición FOR UPDATE se puede usar solo con la adición SINGLE, que puede usar para establecer un bloqueo exclusivo para el registro seleccionado. Sin embargo, esto rara vez se usa y también prefiero usar los módulos de función de bloqueo por separado. Nota: La adición SINGLE no está permitida en una subconsulta y la cláusula ORDER BY no se puede usar junto con ella. CLIENTE ESPECIFICADO Esta adición desactiva el manejo automático de clientes de Open SQL. Cuando se utiliza la adición CLIENTE ESPECIFICADO, la primera columna de las tablas de la base de datos dependiente del cliente se puede especificar en las cláusulas WHERE y ORDER BY.
  • 37. ELIMINANDO EL BÚFER Esta adición hace que la instrucción SELECT omita el almacenamiento en búfer de SAP y lea directamente desde la base de datos y no desde el búfer en el servidor de aplicaciones. FINALIZAR Una instrucción SELECT puede recuperar registros de la base de datos uno por uno (funcionando como un bucle usando la palabra clave INTO), o juntos a la vez (esto se llama "búsqueda de matriz" y se usa con la palabra clave INTO TABLE / APPENDING TABLE). En el primer caso, la sentencia ENDSELECT cierra el ciclo iniciado con SELECT. Ambas construcciones obtienen el mismo resultado. Fuera del alcance de esta publicación de blog Sugerencias de base de datos Básicamente, el uso de sugerencias se usa para especificar cómo el motor de la base de datos debe ejecutar nuestra consulta. Si omite esto, el motor de base de datos utilizará su propio optimizador para determinar la mejor estrategia para ejecutar la instrucción SELECT. El uso de sugerencias para anular esta estrategia predeterminada es bastante frecuente fuera de SAP, pero rara vez se usa con ABAP. Una razón es que no muchos desarrolladores saben que es posible usar sugerencias con declaraciones de OpenSQL (no solo con las nativas). Además, existen ciertos inconvenientes (problemas durante la actualización de la base de datos o el cambio del servidor de la base de datos) y existe una mayor posibilidad de errores humanos. Hay una muy buena descripción general de las sugerencias de la base de datos en la nota de SAP 129385 - Sugerencias de la base de datos en Open SQL
  • 38. Especificación de token dinámico Es posible ensamblar declaraciones OpenSQL durante el tiempo de ejecución. Entonces, en lugar de codificar una declaración SELECT estática, puede usar variables de tipo carácter para contener las cláusulas SELECT, FROM, WHERE, etc. Esto puede resultar útil en ciertos casos, pero tiene desventajas con respecto al rendimiento, la capacidad de mantenimiento y la legibilidad del código. Además, existen ciertas restricciones dependientes de la versión de SAP sobre los elementos de sintaxis permitidos. Hay algunos materiales interesantes en SCN y otros sitios que tratan este tema. Conclusión Como puede ver, aunque Open SQL es un subconjunto muy limitado del lenguaje SQL moderno, aún le permite ejecutar consultas bastante complejas. En la mayoría de los casos, toda la lógica empresarial de un informe complejo no se puede mapear en una sola consulta de selección; sin embargo, si conoce las posibilidades que tiene, puede escribir un código de programa mucho más elegante y compacto con un mejor rendimiento. Gracias por leer y divertirse usando Open SQL.
  • 39. Adición del moderador: el comentario a continuación agrega enlaces a información actualizada muy útil. Thomas Fiedler 28 de mayo de 2014 8:48 a. M. Hola Tamas, muy buena descripción general sobre el tema Open SQL. Hay mucho más en la carretera en NW 7.40. Allí dimos un gran paso adelante con respecto a SQL en ABAP, por ejemplo, una herramienta completamente nueva para definir vistas de bases de datos: Nuevas funciones de modelado de datos en SAP NW ABAP 7.4 SP5 Y también en el lado de las herramientas tenemos mucho más. ¿Conoce las herramientas ABAP basadas en Eclipse con la vista previa de datos para tablas de bases de datos? Presentación de la vista previa de datos en ADT 2.19 Saludos cordiales, Thomas.