Category: Trucos avanzado
Código hermoso
By admin on Sep 21, 2008 | In Aprendiz, Trucos avanzado | Send feedback »
¡Que me disculpen! - Un aplazamiento desde mi ultima entrada pasada. He comenzado un nuevo trabajo que utiliza SQLServer (¡que pena!), así que mi uso de Mysql ha sido muy pequeño últimamente.
Bueno, tomemos a un poco la mirada en la cláusula Group By. Una de las maneras mas comunes que lo utilizo es traer detrás los registros que se duplican más de una vez. Por ejemplo:
Code:
mysql> select ename, job, deptno,count(*) | |
from emp | |
group by ename, job, deptno | |
having count(*) > 1 | |
| |
; | |
+-------+----------+--------+----------+ | |
| ename | job | deptno | count(*) | | |
+-------+----------+--------+----------+ | |
| WARD | SALESMAN | 30 | 2 | | |
+-------+----------+--------+----------+ | |
1 row in set (0.00 sec) |
¿Ahora cómo obtendras (suprimir o actualización) el último parte insertado de este registro duplicado? En este caso hay 2 filas, uno con el empno de 7521, el último fila tiene el empno 8000. El código siguiente (en mi opinión humilde) es muy elegante, y es quizás mi pedacito preferido del sql que he visto...gracias a este libro . libro mysql
Code:
mysql> select * from emp | |
-> where empno not in (select min(empno) | |
-> from emp | |
-> group by ename, job, deptno); | |
| |
+-------+-------+----------+------+------------+------+------+--------+ | |
| empno | ename | job | mgr | hiredate | sal | comm | deptno | | |
+-------+-------+----------+------+------------+------+------+--------+ | |
| 8000 | WARD | SALESMAN | 7698 | 1981-02-22 | 1250 | 500 | 30 | | |
+-------+-------+----------+------+------------+------+------+--------+ | |
1 row in set (0.01 sec) |
Aquí está otra manera de usar la cláusula del Group By (otra vez usando subconsultas) para traer detrás a los empleados con el sueldo más alto y más bajo del grupo de datos.
Code:
mysql> select ename, job, deptno | |
-> from emp | |
-> where sal in ((select min(sal) from emp), | |
-> (select max(sal) from emp)); | |
| |
+-------+-----------+--------+ | |
| ename | job | deptno | | |
+-------+-----------+--------+ | |
| SMITH | CLERK | 20 | | |
| KING | PRESIDENT | 10 | | |
+-------+-----------+--------+ | |
2 rows in set (0.10 sec) |
Ahora que, a mí está también el código hermoso. ¡Disfruta de tu codificación - hasta la próxima!
Variables de SQL
By admin on Jun 16, 2008 | In Trucos avanzado | Send feedback »
El uso de las variables del SQL puede hacer la vida mucho más fácil al procesar datos de las tablas. Puedes asignar un valor vuelto por una consulta SELECT a un variable, después refieres a la variable en tu sesión del mysql. Se nota sin embargo que la variable contiene solamente un solo valor. El sintaxis para asignar una variable dentro de una sentencia SELECT es:
@var_name := value
Una buena demostración de cómo es útil puede ser, es cuando necesitas eliminar filas de datos en tablas múltiples donde las filas son ligadas por un campo común de la identificación (llave extranjera/foreign key). Por ejemplo suponga que tengas los empleados en la tabla del emp que pertenecen al departamento de ' CALLDESK', y necesitas borrar esas filas, y también los registros en otras tablas que se relacionen con departamento de ' CALLDESK'. Primero asignamos nuestra variable con la identificación relevante.
Code:
SELECT @id := deptno | |
FROM dept | |
WHERE dname = 'CALLDESK'; | |
+---------------+ | |
| @id := deptno | | |
+---------------+ | |
| 50 | | |
+---------------+ |
Podemos entonces suprimir filas de las tablas relacionadas:
Code:
DELETE FROM emp where deptno = @id; | |
| |
DELETE FROM dept where deptno = @id; |
Puedes asignar también,a un valor independiente a una variable del SQL, por ejemplo:
Code:
mysql> set @sum = 52 * 350; | |
| |
select @sum; | |
+-------+ | |
| @sum | | |
+-------+ | |
| 18200 | | |
+-------+ |
Así pues, por ejemplo, podrías utilizar esta variable para encontrar todos los contratistas o empleados en tus tablas de base de datos que están ganando más de 350 a la semana durante el año. Por supuesto, esto es un ejemplo muy básico, pero puedes por supuesto hacer el cálculo un poco más difícil. Puedes también poner al día el valor en la variable por ejemplo:
Code:
set @sum = @sum * 1.20; | |
| |
select @sum; | |
+----------+ | |
| @sum | | |
+----------+ | |
| 21840.00 | | |
+----------+ |
Otra manera: Suponga que quieres añadir una columna a una tabla existente y luego quieres fijar un valor con incrementos por 5 para cada fila. Una forma de hacer esto sería crear una nueva tabla basada en la tabla vieja, y después el cambio de nombre a la tabla (ALTER TABLE tname RENAME TO newtname; )
Asignas la variable
SET @id = 0;
Entonces puedes realizar la sentencia INSERT de esta manera:
Code:
INSERT INTO TBL_NEW | |
(field1, field2, field3, new_seq) | |
SELECT field1, field2, field3, | |
@id :=@id+5 | |
FROM TBL_OLD; |
Hay que tener cuidado cuando haces algo similar, como índices y privilegios en la tabla puede tener que ser reconstruido. Sin embargo el INSERT sería normalmente mucho más rápido que haciendo una UPDATE.
Otro ejemplo en cómo usar una variable del SQL puede acelerar cosas. Suponiéndole quieras seleccionar un solo registro al azar de una tabla grande (diga más de 50000 filas), y la tabla tiene un campo del índice de la secuencia. Usando esta declaración de siguiente sea muy lento como MYsql tiene que cargar toda la tabla en una tabla temporal y ordenar todas las filas.
Code:
SELECT * FROM BIG_TABLE | |
ORDER BY RAND() LIMIT 1; |
Una mejor manera de hacer esto sería primero a selecto la cuenta de la tabla en una variable del SQL, y en seguida crearía una figura al azar de eso total.
Code:
SELECT @row_id := count(*) from BIG_TABLE; | |
| |
SELECT @row_id := FLOOR(RAND() * @row_id) + 1; |
Entonces puedes seleccionar la fila de la tabla que tiene un número de serie equivalente al @row_id
Code:
SELECT * from BIG_TABLE | |
WHERE seq_field = @row_id |
Como puedes conjeturar, éste sería mucho más un modo eficaz de recuperar un registro al azar!