Category: Aprendiz
Calcular el promedio o modo en Mysql
By admin on Sep 28, 2010 | In Aprendiz, Trucos avanzado | Send feedback »
Para calcular la media (o promedio) podemos utilizar la función AVG en Mysql.
Code:
select avg(sal) as prom_sal | |
from emp; |
prom_sal
========
2073.9286
Recorda sin embargo que la función no funciona en un campo NULL. Si deseas incluir valores NULL (por ejemplo, asuma un valor cero)
el uso COALESCE cambia por defecto el valor NULL a cero.
select avg(coalesce(sal,0)) as mean_sal
from emp;
Ahora podemos producir la cifra media por columna agrupadas, por ejemplo, por departamento
Code:
select deptno, avg(coalesce(sal,0)) as mean_sal | |
from emp | |
group by deptno; |
deptno mean_sal
====== ========
10 2916.6667
20 2175.0000
30 1568.3333
El modo es el valor que se produce con mayor frecuencia en un determinado conjunto de datos.
Si quiero saber de la tabla Productos, lo que es el modo del campo FULLPRICE de un grupo de productos determinados (en este caso 'CA'), puedo usar una subconsulta para encontrar el modo.
La subconsulta calcula la cuenta diferentes para cada Fullprice, mientras que la parte principal de la consulta se elige el precio que se produce más.
Code:
SELECT FullPrice FROM product | |
WHERE productgroupcode = 'CA' | |
GROUP BY FullPrice | |
HAVING count(*) >= all (SELECT count(*) | |
FROM product | |
WHERE productgroupcode = 'CA' | |
GROUP BY FullPrice) |
FullPrice
=========
14
Hay otro requisito común en la búsqueda de un promedio, que se llama la mediana.
La mediana es el valor del punto medio de un conjunto de elementos ordenados.
Para calcular la mediana se puede utilizar un "SELF-JOIN" o producto cartesiano de una tabla consigo misma (combinación de la tabla a sí mismo), y luego usar la cláusula HAVING para filtrar las filas donde el número de
veces (p. FULLPRICE = P. FULLPRICE) es mayor o igual al número de veces (P. FULLPRICE> P. FULLPRICE):
Code:
SELECT avg(FullPrice) | |
FROM ( select q.FullPrice | |
FROM product q, product p | |
WHERE p.productgroupcode = q.productgroupcode | |
AND q.productgroupcode = 'CA' | |
GROUP BY q.FullPrice | |
HAVING sum(case when q.FullPrice = p.FullPrice then 1 else 0 end) | |
>= abs(sum(sign(q.FullPrice - p.FullPrice))) | |
) t |
avg(FullPrice)
=========
14.0000
Podemos mostrar el resultado de las tareas individuales con el código que se mueve el cálculo SUMA en la sentencia SELECT:
Code:
select q.FullPrice, p.FullPrice, | |
sum(case when q.FullPrice = p.FullPrice then 1 else 0 end) as cnt1, | |
abs(sum(sign(q.FullPrice - p.FullPrice))) as cnt2 | |
FROM product q, product p | |
WHERE p.productgroupcode = q.productgroupcode | |
AND q.productgroupcode = 'CA' | |
group by q.FullPrice |
FullPrice cnt1 cnt2
10 --- 25 --- 130
11 --- 4 --- 38
12 --- 1 --- 16
14 --- 64 --- 56
15 --- 1 --- 2
20 --- 1 --- 4
24 --- 9 --- 24
26 --- 1 --- 12
29 --- 9 --- 48
39 --- 25 --- 120
630 --- 1 --- 30
Por último, aquí voy a enumerar los registros para que pueda ver todo el conjunto con el que trabajamos.
Code:
SELECT PRODUCTID, FULLPRICE | |
FROM product | |
WHERE PRODUCTGROUPCODE = 'CA' | |
ORDER BY FULLPRICE |
PRODUCTID --- FULLPRICE
12175 ---- 10
12014 ---- 10
13297 ---- 10
10002 ---- 10
10003 ---- 10
10838 ---- 11
13109 ---- 11
13107 ---- 12
13299 ---- 14
12177 ---- 14
14030 ---- 14
13621 ---- 14
12016 ---- 14
11003 ---- 14
11057 ---- 14
11056 ---- 14
10001 ---- 15
12949 ---- 20
13360 ---- 24
13470 ---- 24
10955 ---- 24
13359 ---- 26
13298 ---- 29
12015 ---- 29
12176 ---- 29
13024 ---- 39
10863 ---- 39
13023 ---- 39
10862 ---- 39
10993 ---- 39
12141 ---- 630
enlaces
By admin on Feb 16, 2010 | In Aprendiz, Trucos avanzado | Send feedback »
Sólo quería entrar en un par de cosas que son de interés para aquellos que utilizan o programan de Mysql. En primer lugar, si uses Twitter la mejor manera de buscar artículos relacionados con MySQL es entrar #mysql en el campo de búsqueda.
En segundo lugar, este parece ser un enlace ideal para explorar más comandos en Mysql:
sentencias-en-mysql-que-tal-ves-no-conocias
Proyecto Euler 1 en Mysql
By admin on Sep 1, 2009 | In Aprendiz, Trucos avanzado | Send feedback »
Hola, he llegado recientemente a través del Proyecto de Euler http://projecteuler.net/ que plantea retos matemáticos en cualquier lenguaje de codificación que prefieres utilizar.
Entonces no estoy diciendo que MySQL es especialmente apto para afrontar estos retos, pero me preguntaba si yo podría resolver uno o dos solamente por el uso de MySQL.
He aquí la primera cuestión
Si hacemos una lista de los numeros naturales múltiplos de 3 ó 5, menores de 10.
Obtenemos 3,5,6 y 9. La suma de estos múltiplos es 23.
Hallar la suma de todos los multiplos de 3 o 5 menores de 1000.
En primer lugar voy a investigar la forma en que se puede hacer en Perl y luego ver cómo se puede aplicar esto en Mysql. (La siguiente es una adaptación de una solución Perl que he encontrado en Euler_problems_as_perl_oneliners )
#!/usr/bin/perl
# adds each multiple of 3 to $n
# then adds each mutiple of 5 to $n unless divisible by 3
# to avoid duplication!
$n=0;
for($i=3;$i<1000;$i+=3) {$n+=$i}
for($i=5;$i<1000;$i+=5)
{$n+=$i unless $i%3 == 0}
print $n, "\n";
# produces 233168
Por mi código de MySQL voy a empezar por ver cómo probar si un número es divisible por otro número en sql. Una forma es utilizar la función de MOD que devuelve el resto exacto tras la división (Es operación de módulo). Por lo tanto, debe retornar 0, cuando el número es divisible por tu numero de prueba. Asi, select mod(9,3); retorna 0 mientras select mod(8,2); retorna 2.
A continuación, necesitamos una manera de reiterar hasta 999 (es decir, todos los números por debajo de 1000). Suelo usar una tabla llena con números ascendentes para este tipo de tarea; sin embargo, es posible utilizar una técnica de variables, siempre que se inscriba a una tabla de base de datos con el número necesario de filas en él. Por ejemplo, si tenemos una tabla llamada orders con 20.000 registros, se puede traer de vuelta a tan sólo 20 filas numeradas como este:
Code:
select @rownum:=@rownum+1 'row_num', e.* from orders e, | |
(SELECT @rownum:=0) r | |
order by orderid desc limit 20 |
Así, con el fin de traer de vuelta a todos aquellos en los que el row_num campo es divisible por 3, ponemos el código anterior en un SELECT interno (Inner Select):
Code:
select row_num from | |
(select @rownum:=@rownum+1 'row_num' | |
from orders e, | |
(SELECT @rownum:=0) r | |
order by orderid desc limit 20) tmp | |
where mod(row_num,3) = 0; |
Por último añadir una cláusula de OR incluir números divisibles por 5, y suma el resultado:
Code:
select sum(row_num) from | |
(select @rownum:=@rownum+1 'row_num' | |
from orders e, | |
(SELECT @rownum:=0) r | |
order by orderid desc limit 999) tmp | |
where mod(row_num,3) = 0 or mod(row_num,5) = 0; |
Esto da una respuesta de: 233168. Se volvió bastante rápidamente también - apenas 0,08 de segundo! Hasta pronto!