¡Saludos a todos los amantes de SQL!
En Internet, rara vez vi artículos que cubran diferentes puntos de trabajo y sutilezas asociadas con
el procesamiento de datos en SQL .
Me gusta cuando puedes aprender muchas cosas de un artículo a la vez, incluso en términos generales.
Por lo tanto, decidí escribir mi artículo que contenía varias tareas y respuestas con explicaciones para ellas.
Adecuado para aquellos que han dominado bien todas las habilidades básicas y desean desarrollarse más.
Las respuestas proporcionadas son adecuadas para
PostgreSQL (la
mayoría de las tareas serán adecuadas para otros DBMS , pero los resultados y las soluciones pueden ser diferentes. Incluso es interesante donde surgen las diferencias)
Intenta responderte antes de abrir el spoiler.
Vamos!
Intentaré marcar con un asterisco algo puramente para PostgreSQL * (no hay muchos de esos momentos)
1. Un poco sobre operaciones numéricas
1.1 ¿Se cumplirán estas solicitudes? ¿Qué resultados devolverán?
Respuestas a 1.1A) Respuesta: 1
Solo se mostrará toda la parte, porque La operación utiliza enteros. Esto a menudo se encuentra en otros idiomas.
B) Respuesta: la solicitud no se ejecutará .
avg dará un error desde acepta solo números e intervalos de tiempo *
Sin embargo, la función min / max se puede ejecutar en datos de texto (de acuerdo con la clasificación alfabética en la base de datos).
A veces esto puede ser útil cuando necesita al menos mirar una columna que no aparece en GROUP BY
O cuando necesita aplicar la clasificación alfabética a los números, en los que '10' <'2'
B) Respuesta: FALSO
Puede parecer extraño, pero esto es aceptable , porque Esta es una característica de una computadora que representa algunos números de punto flotante; un número puede tomar la forma 7.1 (9)
Recuerdo que una vez traté una solicitud durante mucho tiempo sin saberlo.
D) Respuesta: 0 . El problema es que la expresión entre paréntesis será = 0
SELECCIONAR (20 / 25.0) * 25 funcionaría más correctamente
1.2 Dada la tabla "
tabla_2 " (con una sola columna "
valor " (INTEGER)) que consta de las siguientes 5 filas:
Qué resultado devolverá la consulta:
SELECT (avg(value)*count(*)) - sum(value) FROM table_2;
Opciones de respuesta- -4
- 0 0
- Nulo
- 5 5
- Causará un error porque no especificado GROUP BY
- Ninguno de los listados
Respuesta 1.2respuesta: 5
Las funciones agregadas aplicadas a una columna en particular ignoran NULL , sin embargo, count (*) contará todas las filas
5 * 5 - 20
2. Cuestiones generales
2.1 ¿En qué casos puede una consulta devolver no todo el contenido de una tabla? (
parent_id INTEGER, la tabla se llena con una variedad de datos)
SELECT * FROM any_table WHERE parent_id = parent_id;
¿Cómo se comportará la siguiente solicitud? ¿Qué datos generará?
* PostgreSQL SELECT * FROM any_table WHERE parent_id IS NOT DISTINCT FROM parent_id;
Respuestas a 2.1La primera consulta mostrará todas las entradas excepto aquellas donde parent_id es NULL
La segunda consulta mostrará todas las entradas de la tabla. IS DISTINCT FROM es lógicamente similar al operador ! = En el que NULL es idéntico a NULL
NO ES DISTINTO DE Lógicamente, convierte la desigualdad en igualdad
2.2. ¿Cuál será el resultado de la solicitud?
Respuesta a 2.2El resultado será 2 filas con los valores 1 y 2 , UNION eliminará todos los duplicados en la selección resultante , y no solo entre las dos tablas unidas. Noté que esto no es obvio para todos.
2.3 Escribir una consulta que muestre la fecha de mañana.
Respuesta a 2.3 SELECT CAST((now()+ INTERVAL '1 DAY') AS DATE)
No todos a menudo trabajan con fechas, pero vale la pena dominar un mínimo
* Solución de Postgres, pero creo que otros DBMS no son muy diferentes
Si trabajar con fechas es nuevo para usted, le aconsejo que experimente con la solicitud.
Por ejemplo:
- reemplace DAY con (semana, mes, año, etc.)
- reemplace +1 con -9000
- reemplazar FECHA con HORA
- eliminar CAST
- dejar solo AHORA ()
etc.
Y, inspirado por algunos resultados, lea el
MANUAL , todos los temas allí se describen en detalle
2.4 Las
declaraciones UPDATE ,
DELETE ,
INSERT y
MERGE están diseñadas para manipular datos en tablas. ¿Es
SELECT .. ejecución "segura"? ¿Puede cualquier consulta afectar los datos en la tabla?
Respuesta a 2.4La pregunta puede parecer primitiva, sin embargo ...
Al principio de aprender SQL, tenía la opinión de que esta declaración solo puede mostrar datos, pero:
Además del hecho de que SELECT puede bloquear la tabla para el cambio (BEGIN; SELECT ... FOR UPDATE) *
SELECT puede invocar funciones que pueden realizar casi cualquier manipulación.
Los principiantes deben entender esto de inmediato, y no después de completar la solicitud de "pequeña información" en el servidor de producción
3. Solo PostgreSQL
3.1 Describa lo que sucede cuando esta consulta se ejecuta en el cuadro de diálogo SQL:
SELECT * INTO wtf FROM pg_stat_activity;
Respuesta a 3.1Normalmente, SELECT INTO se usa en funciones
plpgsql para escribir un valor en una variable.
Fuera de plpgsql, el efecto del comando será similar a la consulta a continuación:
CREATE TABLE wtf AS SELECT * FROM pg_stat_activity;
3.2 lo que mostrará esta solicitud "simple"
SELECT wtf_ FROM pg_stat_activity AS wtf_ ;
Respuesta a 3.2Vista del sistema pg_stat_activity (VIEW) de procesos activos en la base de datos.
La peculiaridad de la consulta es que se mostrará una columna con filas (ROW) con TYPE pg_stat_activity (u otra tabla). Necesita saber esto antes para aquellos que escriben funciones. Puede leer más en el
manual.Se agregó la pregunta porque un principiante puede obtener fácilmente ese resultado por error, y no entender lo que ocurre
4. Trabajar con texto. Expresiones regulares
Creo que necesita poder no solo crear consultas, sino también presentar los resultados de la manera correcta.
Las expresiones regulares son un gran tema aparte, con muchos artículos de calidad. Por lo tanto, solo mostraré ejemplos, sin explicaciones detalladas.
4.1. Supongamos que hay una tabla "
tabla_5 " con una columna de texto "
X " y muchas filas diferentes. ¿Qué consulta puede obtener los últimos 10 caracteres de cada línea?
Responder a 4.1SQL le permite encontrar muchas soluciones al mismo problema, por ejemplo:
lo más simple que viene a la mente es lo correcto (X, 10)
regex se puede usar: subcadena (X, '. {0,10} $')
incluso puedes nakostylyat "esquivar" (en todos los sentidos) de esta manera: reverse (substring (reverse (X) for 10))
4.2 Hay una tabla "tabla_6" con una columna de texto "X". La tabla contiene una fila (todo el texto en inglés y ruso solamente):
'Lorem 3 Ipsum 23 standard 7 dummy 17 text Ultimate Answer of Life ?? 777'
A) Escriba una consulta que devolverá los caracteres 42 a 68 de esta cadena
B) ¿Cómo extraer solo letras mayúsculas (ruso o inglés) en una cadena usando SQL?
C) Cómo calcular la suma de números (
no dígitos ) en una cadena usando SQL
Bosquejo SQL WITH table_6(X) AS( SELECT 'Lorem 3 Ipsum 23 standard 7 dummy 17 text Ultimate Answer of Life ?? 777'::TEXT ) SELECT X FROM table_6
4.3 ¿Cómo reemplazar todos los espacios dobles (triples o más) con un solo espacio en el texto (celda de la tabla)? (por tradición: la tabla "
table_7 " con la columna "
X ") (PS será suficiente escribir
SELECT devolviendo el resultado deseado, y no
ACTUALIZAR table_7 ... )
Respuesta a 4.3 WITH table_7(X) AS (SELECT 'Lorem 3 Ipsum 23 standard 7 dummy 11 text'::TEXT)
4.4 Hay una cadena "
X " en la que se permiten errores tipográficos. En lugar de letras rusas (e, o, s, C), se usaron caracteres externos del alfabeto inglés. Reemplace estos caracteres con SQL.
PD La línea debe contener solo caracteres rusos, y no debe preocuparse por un posible cambio en las palabras en inglés.
(Si tiene dificultades para reemplazar todos los personajes, reemplace al menos uno)
Línea de ejemplo:
X = 'Coeo eoc oe'
4.5 Escribir una consulta que convierta una cadena:
' Ivan Ivanov e Ivanovich' a la especie
'Ivan IvanovBúsqueda de bonificación para aquellos que se las arreglaronGenial si hay una función preparada
¿Se puede convertir al revés? (preferiblemente sin perder el relleno).
Quizás la tarea no sea típica, pero será útil para el desarrollo.
'IVANOV IVAN IVANOVICH' se convierte en 'IVANOV IVAN IVANOVICH'
y caso invertido?
Bonus Challenge Response SELECT string_agg(LOWER(LEFT(x,1)) || UPPER(SUBSTRING(x from 2)), '' ORDER BY rn) FROM (SELECT * FROM regexp_split_to_table(' 4 TesT', '\y') WITH ORDINALITY y(x, rn) ) AS z
5. Un poco sobre transacciones
Las transacciones son una cosa muy importante en un DBMS; es importante comprender los puntos principales.
Intentaré simular un ejemplo:
Supongamos que hay una tabla "bienes" con la que van a trabajar dos usuarios.
Tiene una columna de
descuento entero igual a
10 para todas las filas.
La configuración de la base de datos es estándar (LEER COMPROMETIDO - leer datos confirmados).
Usuario
Usuario_1 abre una transacción, ejecuta la siguiente solicitud:
BEGIN; UPDATE goods SET discount = discount + 5;
Un segundo después, otro usuario (
Usuario_2 )
Realiza casi la misma solicitud sin abrir una transacción:
UPDATE goods SET discount = discount + 10;
¿Qué crees que pasará en las siguientes situaciones:
A) ¿Qué resultado obtendrá el Usuario_2 si el Usuario_1 deja la transacción abierta (es decir, no confirma la transacción / no revierte los cambios)?
Lo que verá User_1 a petición:
SELECT discount FROM goods LIMIT 1;
B) ¿Qué sucede si el Usuario_1 hace ROLLBACK? ¿Qué resultados obtendrá User_2?
P) ¿Qué sucede si el Usuario_1 se COMPROMETE? ¿Qué resultados obtendrá User_2?
Las respuestasHasta donde yo sé, READ UN COMMITTED no es compatible con PostgreSQL, y los datos sucios (no confirmados) no se pueden leer
Las respuestas serán las siguientes:
A) Solicitud El usuario_2 esperará por COMPROMISO o ROLLBACK del Usuario_1. (la solicitud parece congelarse)
El usuario_1 en su transacción verá su versión de la instantánea de la base de datos, donde el descuento ya es igual a 15
B) Si el Usuario_1 hace ROLLBACK, entonces el valor del descuento seguirá siendo el mismo, y luego se ejecutará el Usuario_2, que agregará 10 al descuento y el descuento será 20
C) Si el Usuario_1 se COMPROMETE, el valor del descuento aumentará en 5, y luego se ejecutará el Usuario_2, que agregará 10 al descuento y el descuento será 25
Otra versión de esta tarea.Una versión ligeramente diferente de la tarea 13 del usuario
kirill_petrov en READ COMMITTED
¿Qué datos habrá en la tabla?
Conclusión
Creo que eso tocó puntos bastante interesantes.
Espero que las tareas ayuden a motivar a los principiantes, porque es aburrido aprender algo sin metas / objetivos / direcciones específicas.
Puedo alegrarme por aquellos que fueron fáciles de responder a todas las preguntas. Y aquellos que tuvieron dificultades, espero, obtuvieron una
patada en la dirección del desarrollo. Aquellos que no entienden mucho, pero quieren aprender SQL, invito al
curso de jóvenes luchadores de PostgreSQL a mi último artículo.
Espero cualquier adición, solución a problemas especialmente interesantes (puede minar) y otros comentarios.
Gracias por su atencion! ¡Te deseo éxito en aprender SQL!