Tutorial MySQL
#1
[Imagen: mysql.gif?fit=425%2C283]

NIVEL: BÁSICO/MEDIO.

Bueno el fin de este post es mostrar un poco algunas cosas que hay en mysql pero que nadie sabe usar o no usa (porque no saben que existe). Es algo bastante simple y corto ya que el lenguaje SQL es casi infinito (por la cantidad de cosas y variantes que podes hacer). Cualquier duda/error avisen.

Para esta guía, vamos a necesitar algún gestor de DB sea MySQL Workbench o SQLYog.

DB (Base de Datos)

Una base de datos es un sistema de archivos y, en este caso está compuesto por:
  • Tablas
  • Vistas
  • SP`s (Store Procedures)
  • Funciones
  • Triggers
  • Eventos

¿Como creo una base de datos?
Código PHP:
CREATE DATABASE cs
Yo estoy acostumbrado a meter ';' al final de cada consulta. No es necesario, pero es conveniente. En caso que no haya errores debería crearse la db. El error más común es que no se cree la DB porque ya existe.

¿Como uso una base de datos?
Código PHP:
USE cs
Con esta sentencia indicamos que usaremos la DB 'cs' y todo lo que contiene en ella.

¿Porque aclaramos que DB vamos a usar?
Cuando abran algún editor sin tocar nada, hagan un select de alguna tabla de alguna db. Si no esta seteado que usaremos esa DB, nos tirará error.

¿Como muestro todas las DBs?
Código PHP:
SHOW DATABASES

¿Como borro una DB?
Código PHP:
DROP DATABASE cs
Esto eliminara la db 'cs'.


Tablas
¿Que es una tabla?
Habría que buscar una definición concreta de qué es y bla.. yo me la imagino como una matriz donde nosotros definimos las columnas e insertamos filas con datos correspondientes a cada columna.

¿Que tipo campos hay en una tabla?
Cada columna puede variar dependiendo de lo que necesitemos guardar. Estos son los tipos más usados (que no quiere decir que sean los mejores/únicos):
Código PHP:
TINYINT
SHORT
INT
DOUBLE        
[casi a FLOAT]
VARCHAR(X)    [x indica la cantidad de caracterescomo si fuera un array]
TEXT(X)        [igual que arriba]
TIMESTAMP    [se usa para guardar fechas/horas

Otros tipos de campos
Código PHP:
UNIQUE                            [Nos dice que el campo es únicopor ejun usuario en un sistema de cuentas]
PRIMARY KEY                        [Nos dice que es la clave primaria de esa tabla (el identificador)]
FOREIGN KEY REFERENCES 'X'        [Es una clave de la tabla que hace referencia a una clave primaria en otra tabla]
NOT NULL                        [El campo no puede estar vacío]
AUTOINCREMENT                    [Generalmente se usa para los IDs e indica que en cada insert su valor va a ser 1 (o Xmás que el registro anterior]
DEFAULT 
'Y'                        [Setea un valor por defecto al campo]
        
CURRENT TIMESTAMP        [Acá el default imprime el tiempo actual]
SIGNED                            [Signado]
UNSIGNED                        [No signado

Tabla de ejemplo
Código PHP:
CREATE TABLE `usuarios` (
    `
usr_idINT UNSIGNED NOT NULL AUTO_INCREMENT,
    `
usr_nameVARCHAR(32UNIQUE NOT NULL,
    `
usr_pwVARCHAR(32NOT NULL,
    `
usr_emailVARCHAR(50NOT NULL,
    `
usr_tcreatedTIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    
PRIMARY KEY (`usr_id`)) ENGINE=INNODB

Ahora bien, siempre hay estándares y demás para crear todo más lindo y ordenado. Yo no sé si cumplo todos pero al que le doy mucha bola es el de los nombres del campo en una tabla. Yo siempre sigo el de usar una descripción breve de la tabla antes del nombre del campo.
Ejemplo:
Código:
Tabla => 'datos'
Los nombres de los campos en mi tabla van a empezar siempre con 'datos_'+nombre_del_campo
    Ej => 'datos_nivel' o 'datos_color_hud'
Si tengo una FORGEIN KEY => 'datos_'+nombre_tabla_externa+nombre_del_campo
    Ej => 'datos_usuario_id'
De esta forma cuando hagamos un JOIN u otra cosa se lee mucho más claro (en mi opinión).

Otra cosa, yo considero que una tabla está "mal hecha" si no tiene un ID que la identifique. En el ejemplo de Tabla de ejemplo su id es `usr_id`. Pero solo son consideraciones mías.

¿Es recomendable que mi PRIMARY KEY no sea un entero?
Y.. la verdad que no. Esto no implica que no se pueda hacer. Lo mejor es que sea el id de la tabla (por eso considero que si no tiene está mal hecha) ya que es mucho más fácil comparar un número que una string.

¿Como borro una tabla?
Código PHP:
DROP TABLE usuarios
Esto eliminara la tabla 'usuarios'.

Consultas
Consultas o también llamadas Queries es una búsqueda o pedidos de datos a una tabla, dentro de una base de datos.

SELECT

Ejemplo de query que devuelve todos los campos ( * ) en una tabla
Código PHP:
SELECT FROM usuarios

Ejemplo de query que devuelve el id y el email en una tabla
Código PHP:
SELECT usr_idusr_email FROM usuarios

Bien, ahora veremos que tipo de sintaxis se aplica en las consultas.
Código PHP:
FROM 'T'        [Especificamos que usamos los datos de la tabla 'T']
WHERE            [Un condicionalEJ"WHERE usr_id=9;"]
ORDER BY 'Y'    [Ordena la busqueda en referencia a la tabla Y]
LIMIT X            [pone un limite de int:X datos]
TOP      X            [igual a limit]
RAND()            [seleciona de forma alazar (generalmente se usa con LIMIT/TOP)]
(
INNERJOIN    [El inner es opcionalUne dos tablas buscando relacion en sus claves (PRIMARY y FORGEIN)]
LEFT JOIN        [Elige todos los datos de la tabla izquierdatengan o no datos en la de la derecha]
RIGHT JOIN        [Elige todos los datos de la tabla derechatengan o no datos en la de la izquierda]
OUTTER JOIN        [Es lo mismo a hacer un LEFT JOIN+RIGHT JOIN juntostrae todos los datos]
AND             [
Saben lo que es..]
OR                 [
Saben lo que es..]
LIKE 'X'        [Compara 'X' con lo que hay en los campos de la db]
IN (Rango)        [Si esta dentro de un rango]
NOW()            [Devuelve el TIMESTAMP actual en formato de fecha-hora]
BINARY            [Se usa para eliminar el case-sentitive]
LAST_INSERT_ID()    [Devuelve el último id insertado

Ejemplos de consultas simples
Código PHP:
// WHERE
SELECT FROM usuarios WHERE usr_id 2;

// Usando el LIKE
// El '%' indica de que lado queremos que conicida la string.
// Si lo pongo adelante: '%kane' acepta cadenas como 'aaakane' 'basdkane'
// Si lo pongo atrás: 'kane%' acepta cadenas como 'kaneee' 'kane2' 'kaneasd'
// Si lo pongo en ambos: '%kane%' acepta cadenas como 'aaakaneaaa' 'basdkaned21'
SELECT FROM usuarios WHERE usr_name LIKE '%kane%';

// AND ..
SELECT FROM usuarios WHERE usr_id AND usr_email="[email protected]";
// OR ..
SELECT FROM usuarios WHERE usr_id OR usr_email="[email protected]";

// ORDER BY + LIMIT
SELECT FROM usuarios ORDER BY usr_name;
SELECT FROM usuarios ORDER BY usr_name LIMIT 5// Un máximo de 5 

Para mostrar ejemplos de JOIN primero debemos crear otra tabla.
Código:
CREATE TABLE `data` (
    `data_id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
    `data_usr_id` INT UNSIGNED UNIQUE NOT NULL,
    `data_ammopacks` INT UNSIGNED NOT NULL,
    `data_level` INT UNSIGNED NOT NULL,
    `data_reset` INT UNSIGNED NOT NULL,
    PRIMARY KEY (`data_id`)) ENGINE=INNODB;
Ahora tenemos la tabla 'datos'.

Para mostrar LEFT JOIN:
Insertamos algunos datos en la tabla 'usuario' y en la de 'datos'.
Código PHP:
INSERT INTO usuarios (usr_nameusr_pwusr_emailVALUES ("kane""Pw""[email protected]");
INSERT INTO usuarios (usr_nameusr_pwusr_emailVALUES ("cristiano ronaldo""Pw2""[email protected]");
INSERT INTO usuarios (usr_nameusr_pwusr_emailVALUES ("tom cruise""Pw3""[email protected]");
INSERT INTO usuarios (usr_nameusr_pwusr_emailVALUES ("roger federer""Pw4""[email protected]");

INSERT INTO DATA (data_usr_iddata_ammopacksdata_leveldata_resetVALUES (1510);
INSERT INTO DATA (data_usr_iddata_ammopacksdata_leveldata_resetVALUES (2510); 

Con los datos de arriba, si hacemos:
Código PHP:
SELECT FROM usuarios LEFT JOIN `dataON usr_id data_usr_id

Obtenemos
[Imagen: MIFPiJ6.png?1]
Como vemos, no hay datos en la tabla 'datos' con los ids que buscamos por eso sale NULL.

Para mostrar RIGHT JOIN:
Insertamos algunos datos en la tabla 'usuario' y en la de 'datos'.
Código PHP:
INSERT INTO usuarios (usr_nameusr_pwusr_emailVALUES ("kane""Pw""[email protected]");
INSERT INTO usuarios (usr_nameusr_pwusr_emailVALUES ("cristiano ronaldo""Pw2""[email protected]");

INSERT INTO DATA (data_usr_iddata_ammopacksdata_leveldata_resetVALUES (1510);
INSERT INTO DATA (data_usr_iddata_ammopacksdata_leveldata_resetVALUES (2510);
INSERT INTO DATA (data_usr_iddata_ammopacksdata_leveldata_resetVALUES (3510);
INSERT INTO DATA (data_usr_iddata_ammopacksdata_leveldata_resetVALUES (4510); 

Con los datos de arriba, si hacemos:
Código PHP:
SELECT FROM usuarios RIGHT JOIN `dataON usr_id data_usr_id

Obtenemos
[Imagen: bSpR46p.png?1]
Como vemos, no hay datos en la tabla 'usuarios' con los ids que buscamos por eso sale NULL.

Para mostrar OUTTER JOIN:
Insertamos algunos datos en la tabla 'usuario' y en la de 'datos'.
Código PHP:
INSERT INTO usuarios (usr_nameusr_pwusr_emailVALUES ("kane""Pw""[email protected]");
INSERT INTO usuarios (usr_nameusr_pwusr_emailVALUES ("cristiano ronaldo""Pw2""[email protected]");
INSERT INTO usuarios (usr_nameusr_pwusr_emailVALUES ("roger federer""Pw3""[email protected]");

INSERT INTO DATA (data_usr_iddata_ammopacksdata_leveldata_resetVALUES (1510);
INSERT INTO DATA (data_usr_iddata_ammopacksdata_leveldata_resetVALUES (2510);
INSERT INTO DATA (data_usr_iddata_ammopacksdata_leveldata_resetVALUES (4510);
INSERT INTO DATA (data_usr_iddata_ammopacksdata_leveldata_resetVALUES (5510); 

Con los datos de arriba, si hacemos:
Código PHP:
SELECT FROM usuarios LEFT JOIN `dataON usr_id data_usr_id
UNION
SELECT 
FROM usuarios RIGHT JOIN `dataON usr_id data_usr_id

Obtenemos
[Imagen: VZFaU3K.png?1]
Los que buscamos y no se encuentran sale NULL.

**LOS DATOS FUERON MODIFICADOS PARA MOSTRAR LOS FUNCIONAMIENTOS

- Bien ahora pasamos a otros aspectos importantes de las consultas.


INSERT
Acá una breve descripción de como insertar datos en una tabla.
Código:
INSERT INTO table_name ( field1, field2,...fieldN )
   VALUES
   ( value1, value2,...valueN );
Para esto debemos tener una tabla ya existente.
Ej con la tabla usuarios:
Código PHP:
INSERT INTO usuarios (usr_nameusr_pwusr_emailVALUES ("kane""Pw""[email protected]"); 

UPDATE
Acá una breve descripción de como actualizar datos en una tabla.
Código:
UPDATE table_name
SET column1=value, column2=value2,...
WHERE some_column=some_value
Nota: no podemos actualizar datos si no fueron insertados antes.

Ej con la tabla usuarios:
Código PHP:
UPDATE usuarios
SET usr_pw 
"kane"
WHERE usr_name "kane"
Si lo ejecutamos la nueva contraseña debería ser 'kane'.

DELETE
Acá una breve descripción de como eliminar datos de una tabla.
Código:
DELETE FROM table_name
WHERE some_column = some_value

Ej con la tabla usuarios:
Código PHP:
DELETE FROM usuarios
WHERE usr_name 
"kane"
Si lo ejecutamos debería borrar el registro con usuario igual a 'kane'. Obviamente acá en vez de '=' podemos usar LIKE y borrar más.

TIP: Para borrar todos los registros de una tabla (sin borrar la tabla)
Código PHP:
DELETE FROM usuarios
WHERE 1
=1

¿Como muestro todas las tablas en una DB?
Código PHP:
USE nombre_db;
SHOW TABLES

Hay muchísimas variantes y todo, pero este post sería eterno si las escribo.

SP´s
Los SP´s o Stored Procedures son subrutinas (como si fueran funciones) que tienen un nombre, parámetros y un resultado. Son muy rápidos, porque están precompilados y almacenados con el motor de la db.

Para crear un SP
Código:
CREATE [DEFINER = { user | CURRENT_USER }]          
PROCEDURE sp_name ([proc_parameter[,...]])          
[characteristic ...] routine_body    
proc_parameter: [ IN | OUT | INOUT ] param_name type    
type:          
Any valid MySQL data type    
characteristic:          
COMMENT 'string'    
| LANGUAGE SQL      
| [NOT] DETERMINISTIC      
| { CONTAINS SQL | NO SQL | READS SQL DATA
| MODIFIES SQL DATA }      
| SQL SECURITY { DEFINER | INVOKER }    
routine_body:      
Valid SQL routine statement

Los parámetros de un SP pueden ser de entrada (IN) o salida (OUT) y hay que especificar que tipo es el que entra/sale (INT, VARCHAR(), DOUBLE, etc).

Ejemplo:
Código PHP:
DELIMITER $$
CREATE PROCEDURE guardar_datos (IN player_id INTIN player_ammopacks INTIN player_level INTIN player_reset INT)
BEGIN
    UPDATE 
`datosSET data_ammopacks=player_ammopacksdata_level=player_leveldata_reset=player_reset
    WHERE data_usr_id 
player_id;
END $$
DELIMITER 
Este ejemplo es para guardar los datos de un jugador. Tiene 4 parámetros de entrada. Entonces para guardar los datos del jugador en vez de hacer un update enorme a simple viste y crear el típico szQuery[2048], hacemos:

Código PHP:
// Guardad de datos
new query[100];
formatex(query99"CALL guardar_datos(%d, %d, %d, %d);"g_player_id[id], g_ammopacks[id], g_level[id], g_reset[id]);

SQL_QueryAndIgnore(tuplaquery); 
Como ven, los SP`s se llaman usando la función CALL y no SELECT (aunque no estoy seguro si con select funcionaría).

Repito, hay muchísimas cosas para hacer y no voy a hacerlas todas. Es para que tengan una idea de como simplificar todo.

Vistas
Una vista almacena varias consultas que devuelven un conjunto de resultados, conformándose como una tabla.
Para crear una vista:
Código:
CREATE [OR REPLACE] VIEW nombre_vista [lista_columnas]
AS consulta
La 'consulta' se trata de hacer un SELECT que nos devuelva los datos.
Cuando se crea una vista con 'OR REPLACE', se creará la vista si no existe una con el mismo nombre y, si existe, se reemplazará por ésta.

¿Para que sirven las vistas?
Te ahorras hacer varias consultas ya que creas una 'tabla virtual' con todos los datos.

Ejemplo de una vista
Código:
CREATE VIEW player_data AS
    SELECT * FROM usuarios JOIN `data` ON usr_id = data_usr_id;
De esta forma tenemos creada la vista.
Ahora bien, si yo inserto los siguientes datos:
Código PHP:
INSERT INTO usuarios (usr_nameusr_pwusr_emailVALUES ("kane""Pw""[email protected]");
INSERT INTO usuarios (usr_nameusr_pwusr_emailVALUES ("cristiano ronaldo""Pw2""[email protected]");
INSERT INTO usuarios (usr_nameusr_pwusr_emailVALUES ("roger federer""Pw3""[email protected]");

INSERT INTO DATA (data_usr_iddata_ammopacksdata_leveldata_resetVALUES (1510);
INSERT INTO DATA (data_usr_iddata_ammopacksdata_leveldata_resetVALUES (2510);
INSERT INTO DATA (data_usr_iddata_ammopacksdata_leveldata_resetVALUES (3510); 

Y llamo a la vista:
Código PHP:
SELECT FROM player_data

Obtengo:
[Imagen: N6EugU3.png?1]

La vista siempre se mantiene actualizada, porque es simplemente un select. Hay vistas que soportan ser actualizadas, borrar registro o insertar datos. Pero lo mejor es hacerlo en las tablas correspondientes y dejar que la vista solo muestre los resultados.

¿Como borro una vista?
Código:
DROP VIEW nombre_vista;

¿Más información de vistas?
Acá


Triggers
Trigger = Gatillo
Si apretás el gatillo se dispara algo, en éste caso una o varias consultas.
La principal diferencia entre un SP y un trigger, es que el trigger se hace de forma automática.

Para crear un trigger
Código:
DELIMITER $$

USE `nombre_de_mi_db`$$

DROP TRIGGER IF EXISTS `nombre_trigger`$$

CREATE
    TRIGGER `nombre_trigger`
    {BEFORE|AFTER} {INSERT|UPDATE|DELETE} ON `nombre_tabla`
    FOR EACH ROW
    BEGIN
        ACÁ LA CONSULTA;
    END;
$$

DELIMITER ;

Supongamos que tenemos un zp con las tablas usuarios y datos (las de arriba), entre otras. Yo me creo un usuarios y obtengo el ID. Pero ese ID lo tengo que meter en varias tablas. En vez de hacerlo manualmente una por una, creamos un trigger que las meta.
Ejemplo
Código PHP:
DELIMITER $$

USE `
cs`$$

DROP TRIGGER /*!50032 IF EXISTS */ `meter_ids`$$

CREATE
    
/*!50017 DEFINER = 'root'@'localhost' */
    
TRIGGER `meter_idsAFTER INSERT ON `usuarios
    FOR 
EACH ROW 
    BEGIN
    INSERT INTO 
`data` (data_usr_iddata_ammopacksdata_leveldata_resetVALUES (NEW.usr_id510);
    
END;
$$

DELIMITER 
Bien este trigger lo que hacer es insertar en la tabla datos el id del nuevo usuarios y LOS VALORES PREDETERMINADOS QUE YO FIJO en cada campo (generalmente ponen g_level[id] = 1; en client_putinserver, bueno eso ya no se usaría porque de acá seteamos los valores predeterminados). Puse que el reset con el que arranca es 0 y los ammopacks 5.

Para probarlo, creamos un nuevo usuario
Código PHP:
INSERT INTO usuarios (usr_nameusr_pwusr_emailVALUES ("jessie kriel""Pw6""[email protected]"); 

Una vez que se haya creado exitosa-mente el usuario, hacemos un join:
Código PHP:
SELECT FROM usuarios JOIN `dataON usr_id data_usr_id

Y nos debería aparecer nuestro nuevo usuario con los datos predeterminados en el trigger.

Esto es lo básico de lo básico, es como gatear. Se pueden hacer muchísimas cosas más interesantes, pero por algo hay que empezar.

Nota: Fíjense que use NEW.usr_id porque el trigger se hace DESPUÉS de insertar. Si fuera antes de actualizar (por ejemplo) tendría que usar OLD.usr_id.

Nota2: Hasta donde sé, solo puede haber un trigger del mismo tipo por tabla. Es decir, no puedo tener 2 triggers que utilicen AFTER INSERT en una misma tabla; pero si uno AFTER INSERT y otro BEFORE INSERT


Manejo de Tiempo
Bueno todos saben que el uso de fechas es algo bastante jodido (va, ami me cuesta). Una de las ventajas de MySQL es la cantidad de funciones que tiene acerca de este tema. Empezamos:

Huso horario
Bueno esto es importante y cuesta un poco entenderlo/aprenderlo (es un poco confuso).
Wikipedia dice: Un huso horario es cada una de las 24 áreas en que se divide la Tierra, por un meridiano y en las que rige por convención el mismo horario.


¿Que es UNIX_TIMESTAMP?
Wikipedia dice: El Tiempo Unix es un sistema para la descripción de instantes de tiempo: se define como la cantidad de segundos transcurridos desde la medianoche UTC del 1 de enero de 1970. Todos los husos horarios se definen en relación con el denominado tiempo universal coordinado (UTC), huso horario centrado sobre el meridiano de Greenwich.

Bien de este simple párrafo de wiki sacamos una sigla MUY importante => UTC
El UTC es el standard por el que se "intenta regular" el tiempo.

En Argentina por ejemplo, el uso horario es denominado HOA (hora oficial de argentina) y es igual a: UTC-03:00

Hay muchas cosas para explicar, pero no viene al caso con el post. Es muy interesante, les sugiero que investiguen. Esto lo menciono porque, no solo en programación, sino hasta en la TV cuando queremos ver un partido de fútbol que dice:
Mañana no te pierdas "real vs bla" a las '15 hs' Ciudad de México (GMT-5) y 'X' de buenos aires (UTC-3).

Es un ejemplo para que entiendan, y sepan que és. Por más que no vuelva a hacer referencia de ésto más adelante en el post.


UNIX_TIMESTAMP en MySQL
En mysql se puede usar esta funcion con el siguiente comando:
Código:
// Sin parametros
SELECT UNIX_TIMESTAMP() as segundos;

// Son las 15:12 en Argentina
// Al ejecutar esto obtendremos:
+------------+
|  segundos     |
+------------+
| 1563732709 |
+------------+

// Si llamamos a UNIX_TIMESTAMP() sin argumentos devuelve un timestamp Unix como un entero no signado.
// ------------------------------------------------------

// Con parametros como fecha+hora
// Sintaxis: UNIX_TIMESTAMP(date)
//        donde date es =>
//                            cadena DATE
//                            cadena DATETIME
//                            TIMESTAMP
//                            Número en formato YYYY-MM-DD
SELECT UNIX_TIMESTAMP('2019-07-21 15:14:00') as segundos;

+------------+
|  segundos     |
+------------+
| 1563732840 |
+------------+

// Si es llamada con un argumento fecha, devuelve el valor del argumento como segundos desde '1970-01-01 00:00:00' GMT

Con esto dicho, vamos a las funciones mas usadas:
Código PHP:
ADDDATE(exprdays)            [Le suma 'days' días a la fecha pasa como 'expr']
EjSELECT ADDDATE('2019-07-21'30);
Devuelve'2019-08-20'

CURDATE()        [Devuelve el día actual]
Ej:    SELECT CURDATE();
Devuelve2019-07-21
// Tiene variantes como CURRENT_DATE() que es lo mismo.

CURTIME()        [Devuelve la hora actual]
Ej:    SELECT CURTIME();
Devuelve15:33:57
// Tiene variantes como CURRENT_DATE() que es lo mismo.

NOW()            [Devuelve un timestamp con la fecha+hora]
Ej:    SELECT NOW();
Devuelve'2019-07-21 15:33:57'
// Tiene variantes como CURRENT_TIMESTAMP() o LOCALTIME() que es lo mismo.

DATE(expr)        [Extrae la parte de la fecha de la expr]
Ej:    SELECT DATE('2019-07-21 15:33:57');
Devuelve'2019-07-21'


DATE_ADD(dateINTERVAL expr unit)    [Lo mismo que ADDDATE pero con intervalos]

Ej:        SELECT DATE_ADD('2019-07-21'INTERVAL 1 DAY);
Devuelve'2019-07-22'

Ej2:    SELECT DATE_ADD('2019-07-21'INTERVAL 1 MONTH);
Devuelve'2019-08-21'

Ej3:    SELECT DATE_ADD('2019-07-21'INTERVAL 1 YEAR);
Devuelve'2020-07-21'


DATE_SUB(dateINTERVAL expr unit)    [Igual a DATE_ADD pero en vez de sumarresta los días]



FROM_UNIXTIME(unix_timestamp[,format])

Ej:        SELECT FROM_UNIXTIME(1563721200);
Devuelve'2019-07-21 12:00:00'

Ej2:    SELECT FROM_UNIXTIME(1563721200'%Y %D %M %h:%i:%s');
Devuelve'2019 21st July 12:00:00'


TIMEDIFF(expr1,expr2)        [Devuelve la diferencia de fechas expresada como tiempo]
Ej:    SELECT TIMEDIFF('2019-07-21 00:00:00''2019-07-01 00:00:00');
Devuelve'480:00:00' -> eso implica que hay 480 hs de diferencia entre fechas (20 días)


UNIX_TIMESTAMP([expr,..])        [Esta explicado arriba

Según la página de MySQL, dejó la siguiente nota:
Código:
If you use UNIX_TIMESTAMP() and FROM_UNIXTIME() to convert between values in a non-UTC time zone and Unix timestamp values, the conversion is lossy because the mapping is not one-to-one in both directions.

Bien, hay muchisimas más funciones relacionadas al tiempo pero solo mostré las que consideraba mas importantes.


Como regalo le dejo todo esto hecho para crear admins (vi varios y son horrendos, hacen todo por pawn cuando mysql te lo resuelve en dos pasos). Esto está relacionado a la tabla usuarios de arriba de todo.

1º: Crear la tabla de admins
Código PHP:
CREATE TABLE `admins` (
    `
adm_idINT UNSIGNED NOT NULL AUTO_INCREMENT,
    `
adm_usr_idINT UNSIGNED NOT NULL UNIQUE,
    `
adm_pwVARCHAR(32NOT NULL,
    `
adm_flagsVARCHAR(32NOT NULL,
    `
adm_creadoTIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    `
adm_finalizaTIMESTAMP NULL,
    
PRIMARY KEY (`adm_id`)) ENGINE=INNODB

2º: Creamos un store procedure para crear el admin
Código PHP:
DELIMITER $$
CREATE PROCEDURE crear_adminIN usr_id INTIN adm_pass VARCHAR(32), IN adm_flags VARCHAR(32), IN meses INT )
BEGIN
    
-- Variables
    
DECLARE fecha_venc DATETIME;
    
    -- 
Declaramos la fecha de vencimiento
    SELECT DATE_ADD
NOW(), INTERVAL meses MONTH INTO fecha_venc;
    
    -- 
Creamos el adm
    REPLACE INTO admins 
(adm_usr_idadm_pwadm_flagsadm_finalizaVALUES (usr_idadm_passadm_flagsfecha_venc);
END $$
DELIMITER 

3º: Creamos una vista que devuelva solo los admins con el vencimiento NO vencido.
Código PHP:
CREATE VIEW get_admins AS
    
SELECT usr_idusr_nameadm_finaliza FROM usuarios JOIN admins ON usr_id adm_usr_id WHERE adm_finaliza NOW(); 

Listo! Ahora solo con hacer:
Código PHP:
SELECT from get_admins
Nos devuelven los admins que no se han vencido aún! Magia.
(Habría que pulirlo un poco pero funciona perfecto, por lo menos con las pruebas que hice).


Éstos, a su vez, son cosas que pueden usar dentro de PAWN.
No subí ejemplos concretos de PAWN porque sino limito a un solo lenguaje. Pero lo hice lo más claro que pude y con referencias al zp para que a su vez sea mas entendible.
Espero que les haya gustado.

PD: Hay muchas opiniones personales, ésto no significa que sea la mejor/única forma de hacerlo.
PD2: Si tienen dudas pregunten, en lo posible intenten probar y después preguntar...
(19/06/2014, 11:08 PM)01011001 escribió: No tiene niveles infinitos, llega hasta 2147483648 (Y despues hace un integer overflow)

(19/06/2014, 11:08 PM)[R]ak escribió: Mis conocimientos aumentaron un 500% con este post
Responder
#2
Excelente tutorial, se necesitaba algo asi en el foro..

Saludos. Crab
Responder
#3
(19/07/2019, 04:40 PM)Chema escribió: Excelente tutorial, se necesitaba algo asi en el foro..

Saludos. Crab

Responder
#4
(19/07/2019, 05:42 PM)Skylar escribió:
(19/07/2019, 04:40 PM)Chema escribió: Excelente tutorial, se necesitaba algo asi en el foro..

Saludos. Crab
Responder
#5
(19/07/2019, 05:49 PM)Pan Bimbo (? escribió:
(19/07/2019, 05:42 PM)Skylar escribió:
(19/07/2019, 04:40 PM)Chema escribió: Excelente tutorial, se necesitaba algo asi en el foro..

Saludos. Crab
[Imagen: 76561198350936449.png]

Cita:Los precios en la moneda venezolana se fijarán a partir de la reconversión monetaria y valdrá mucho menos de lo que cuesta una Cachapa con queso.
Responder
#6
(19/07/2019, 04:10 PM)Kane escribió:
Código:
UPDATE table_name
SET column1=value, column2=value2,...
WHERE some_column=some_value

También sumandole valores o restandole como quieras que sea la operación
Código:
UPDATE table_name
SET column1=column1 + 10, column2=column2 + 50,...
WHERE some_column=some_value
[Imagen: b_350_20_323957_202743_f19a15_111111.png]

(18/11/2014, 05:47 PM)Neeeeeeeeeel.- escribió: Por qué necesitan una guía para todo? Meté mano y que salga lo que salga... es la mejor forma de aprender.

(16/05/2016, 11:08 PM)kikizon2 escribió: No cabe duda que tienen mierda en vez de cerebro, par de pendejos v:
Responder
#7
(19/07/2019, 09:36 PM)OsweRRR escribió:
(19/07/2019, 04:10 PM)Kane escribió:
Código:
UPDATE table_name
SET column1=value, column2=value2,...
WHERE some_column=some_value

También sumandole valores o restandole como quieras que sea la operación
Código:
UPDATE table_name
SET column1=column1 + 10, column2=column2 + 50,...
WHERE some_column=some_value
Es lo mismo, sigue siendo un valor..
(19/06/2014, 11:08 PM)01011001 escribió: No tiene niveles infinitos, llega hasta 2147483648 (Y despues hace un integer overflow)

(19/06/2014, 11:08 PM)[R]ak escribió: Mis conocimientos aumentaron un 500% con este post
Responder
#8
Podrías agregar algo de indices también, que son bastantes utilizados en el tema de buscar datos en muchos registros.
Responder
#9
Te faltaría el uso de unixtime en mysql.
Responder
#10
(20/07/2019, 02:50 AM)INTIFADA escribió: Podrías agregar algo de indices también, que son bastantes utilizados en el tema de buscar datos en muchos registros.
Si, no se me había ocurrido.. dejame pensar una forma interesante de mostrar el funcionamiento (aunque son obvias pero las tengo que hacer ajjaja)

(20/07/2019, 12:21 PM)Niper.-. escribió: Te faltaría el uso de unixtime en mysql.
Que querés saber de eso??
(19/06/2014, 11:08 PM)01011001 escribió: No tiene niveles infinitos, llega hasta 2147483648 (Y despues hace un integer overflow)

(19/06/2014, 11:08 PM)[R]ak escribió: Mis conocimientos aumentaron un 500% con este post
Responder
#11
(21/07/2019, 06:41 AM)Kane escribió:
(20/07/2019, 12:21 PM)Niper.-. escribió: Te faltaría el uso de unixtime en mysql.
Que querés saber de eso??

Yo, nada. Pero la gente le debería interesar, puesto que podes hacer muchas cosas controlando el tiempo via mysql(UNIX_TIMESTAMP) y vía pawn (get_systime). Ya que por ejemplo, podes controlar las fechas de un admin para hacer un vencimiento.
Además que mysql tiene otras formas igual de controlar el tiempo, mysql_days, mysql_date, mysql_date_add, etc. Pero bueno, es por si queres nomas, todo sirve para mejorar el aprendizaje, verdad?
Responder
#12
(21/07/2019, 09:58 AM)Niper.-. escribió: Yo, nada. Pero la gente le debería interesar, puesto que podes hacer muchas cosas controlando el tiempo via mysql(UNIX_TIMESTAMP) y vía pawn (get_systime). Ya que por ejemplo, podes controlar las fechas de un admin para hacer un vencimiento.
Además que mysql tiene otras formas igual de controlar el tiempo, mysql_days, mysql_date, mysql_date_add, etc. Pero bueno, es por si queres nomas, todo sirve para mejorar el aprendizaje, verdad?
Ahí actualice. Nunca escuché hablar de mysql_date, mysql_date_add ni idea.
Si obvio todo sirve, pero como dije en el post es imposible mostrar todo. También falta los ALTER, TRUNCATE, etc.
Espero que esté todo, dentro de todo, bien explicado
(19/06/2014, 11:08 PM)01011001 escribió: No tiene niveles infinitos, llega hasta 2147483648 (Y despues hace un integer overflow)

(19/06/2014, 11:08 PM)[R]ak escribió: Mis conocimientos aumentaron un 500% con este post
Responder


Salto de foro:


Usuarios navegando en este tema: 1 invitado(s)