~~stoggle_buttons~~ ====== Links ====== * [[https://jvns.ca/blog/2019/10/03/sql-queries-don-t-start-with-select/|SQL queries run in this order]] * [[https://developer.okta.com/blog/2019/07/19/mysql-vs-postgres|MySQL vs PostgreSQL -- Choose the Right Database for Your Project]] ====== MySQL ====== ===== Info de espacio libre ===== -- Get the database free space SELECT table_schema "Data Base Name", sum( data_length + index_length ) / 1024 / 1024 "Data Base Size in MB", sum( data_free )/ 1024 / 1024 "Free Space in MB" FROM information_schema.TABLES GROUP BY table_schema; -- Get the database last update ordered by update time then by create time. SELECT MAX(UPDATE_TIME), MAX(CREATE_TIME), TABLE_SCHEMA FROM `TABLES` GROUP BY TABLE_SCHEMA ORDER BY 1, 2; * [[http://mysqladministrators.blogspot.com/2012/02/get-database-size.html]] ===== Simular lag en MySQL ===== [[https://stackoverflow.com/questions/11303532/simulate-lag-function-in-mysql]] ===== Matar procesos que se quedan abiertos desde MySQL ===== SHOW PROCESSLIST; KILL 38239; KILL 38240; -- Para hacerlo más automático, se puede hacer lo sigiente: -- También matchea el propio proceso que ejecuta la query, -- por lo que siempre devuelve un resultado al menos select concat('KILL ',id,';') from information_schema.processlist where INFO like "%FaultyTable%" [[https://stackoverflow.com/questions/24496918/mysql-slow-drop-table-command]] ===== Backup de una tabla ===== CREATE TABLE db.backup LIKE db.mytable; INSERT db.backup SELECT * FROM db.mytable; ===== MySQL Time Type ===== * https://dev.mysql.com/doc/refman/8.0/en/time.html * https://stackoverflow.com/questions/1426100/adding-certain-minutes-to-time-in-mysql/47887005 ====== PostgreSQL ====== ===== conexiones sencillas con url ===== ''%%psql "postgres://postgres:postgres@localhost:5432/postgres"%%'' ===== Importar a una tabla desde un csv ===== **Mucho cuidado porque el orden de los campos importa** psql "$POSTGRES_DATABASE_URI" -c "\copy table_name from 'file.csv' delimiter ',' csv header;" file="table.csv"; tail -n +2 $file | psql -d mydb -U postgres -W -h localhost -p 5432 -c "COPY landing_tbl ( $(head -n 1 $file) ) FROM STDIN CSV;" El ''tail -n +2'' se salta el encabezado del csv, el ''head -n 1 final.csv'' nos saca el encabezado para la lista de campos ===== Update con join ===== update new_table set field = b.field from backup b where b.created_at = new_table.created_at and b.id = new_table.id and b.field is not null ===== Contraseña postgres ===== * PostgreSQL por defecto no tiene contraseña y no se puede acceder a ella. Hay que hacer: * ''%%sudo -u postgres psql -c "ALTER USER postgres PASSWORD 'postgres';"%%'' * ''psql -d postgres -U postgres -W -h localhost -p 5432'' para comprobar que funciona ===== updates csv ===== * Tener una tabla temporal intermedia para la copia. Al añadir columnas a la tabla final, no se rompe el proceso que insertaba en esa tabla, y si cambias el CSV, tienes que cambiar la temporal * Aprovechar ese paso intermedio para intentar no perder registros, p.e. haciendo un [[https://www.postgresqltutorial.com/postgresql-upsert/|upsert]] en la tabla final desde la temporal Script de upsert SQL begin; create temporary table temp_mytable as select :fields_list from :dest_table where 1 <> 1; \copy temp_mytable from ':filename' delimiter ',' csv; insert into :dest_table(:fields_list) select :fields_list from temp_mytable on conflict (:pkey_fields_list) do update set :update_set; commit; ===== backups ===== # Primero hay que levantar un proxy a PROD para conectarnos a ella en localhost:54321 (según el ejemplo) psql "postgres://postgres:postgres@localhost:5432/postgres" -c "\copy tablename to tablename.csv delimiter ',' csv header" pg_dump "postgres://postgres:postgres@localhost:5432/postgres" > out.sql psql "postgres://postgres:postgres@localhost:5432/postgres" < out.sql ====== dbeaver ====== ===== exportar queries sin ejecutarlas ===== [[https://stackoverflow.com/questions/43329790/export-result-set-on-dbeaver-to-csv]] Seleccionar Query > Execute > Export from query ====== Patrones SQL ====== ===== Seleccionar último registro ===== select * from mytable join ( select max(created_at) from mytable group by id ) latest on mytable.id = latest.id ===== Upsert ===== Al subir un csv, el orden de campos importa, por lo que es mejor: - Subir la tabla a una tabla temporal asegurándonos de que tiene el mismo esquema (o creándolo automáticamente en python, por ejemplo) - Hacer un **upsert** (update+insert) de los campos que hemos incluido ===== lag, nulos ===== Cuando haces un lag, te salen nulos timestamp > lag(timestamp) -- OJO! Esto excluye registros con timestamp nulo! timestamp > coalesce(lag(timestamp), min_timestamp) ====== Trucos ====== * Al atascarse en una query, puede ser útil cambiar el orden en el que se ejecutan las queries: sacar una subquery al nivel superior, hacer primero un cruce que se hace más adelante... ===== Cuentas distintas sobre una misma tabla ===== select c.name->>"$.translations.en" as "Ciudad", coalesce(created_at, 0) as "Día", coalesce(sum(created_at >= '2020-04-01 02:00:00' and created_at < '2020-05-01 02:00:00'), 0) as "Registrados", coalesce(sum(accept_date >= '2020-04-01 02:00:00' and accept_date < '2020-05-01 02:00:00'), 0) as "Validados" from motit.iterable i left join motit.`User` u on i.num = date(u.created_at) left join motit.City c on u.city_id = c.id where created_at >= '2020-04-01 02:00:00' and created_at < '2020-05-01 02:00:00' group by 1, 2 order by c.name->>"$.translations.en", date(created_at) Básicamente haces un select sum(condición 1 que iria en el where) as cuenta1, sum(condición 2 que iria en el where) as cuenta2