Category: Aprendiz
Problemas de importación de los campos de fecha de Excel
By admin on Jun 11, 2009 | In Aprendiz | Send feedback »
Yo quería importar los siguientes datos de una hoja de cálculo en mi tabla de base de datos
Code:
orderid customerid orderdate city | |
800 15 15/02/09 London | |
801 22 22/02/09 Glasgow | |
802 15 20/03/09 London | |
803 24 21/03/09 Aberdeen | |
804 76 13/04/09 Grimsby |
Después de guardar la hoja de cálculo en formato CSV (delimitado por comas) fue mi primer intento de utilizar la sintaxis del comando "LOAD DATA".
Code:
LOAD DATA INFILE 'C:\\ordertest.csv' INTO TABLE testorders | |
LINES terminated BY '\n'; |
Había leído que esto rara vez funciona, así no me sorprendió encontrar problemas en los datos insertados (aunque por lo menos hizo algunos intentos de poblar la tabla desde el archivo).
Por lo tanto, decidí utilizar el mecanismo de IMPORT en phpMyAdmin, después de la primera selección de la tabla necesario. Una opción útil es especificar aquí el número de registros para saltar desde el comienzo del archivo - esto me permitió pasar el registro cabecera (nombres de campo) de que no desea importar. Sin embargo las opciones por defecto me falle. El "FIELDS TERMINATED BY" caja tiene un defecto de ";" cuando lo necesitamos ",". De todos modos, después de corregir esto mediante la introducción de la coma, estaba en condiciones de importar los registros. Sin embargo todavía había un problema - la fecha de todas las columnas mostró 00/00/00. Esto se debe a que MySQL usa el formato de una fecha diferente a Microsoft Excel. Cómo encontrar la solución a esto? Volví a la hoja Excel y cambiar el formato del campo a la fecha yyyy-mm-dd (formato de ingles, es aaaa-mm-dd en espanol?) antes de guardar como un archivo CSV (delimitado por comas) y pasar por el proceso de nuevo. Al final he podido importar los datos que yo quería.
Otras soluciones podrían haber incluyó el uso de OpenOffice para crear la hoja de cálculo y csv, usando ODBC preguntas en Mysql, usando Navicat, php o utilizando un programa para leer e importar los datos.
Espero a ver estas opciones en futuros artículos.
Por cierto, en el pasado, cuando hacia la transferencia de datos de hojas de cálculo en bases de datos he utilizado la siguiente técnica. Uso la función de Excel "concatenar" para crear una declaración de sql INSERT en una sola línea y, a continuación, copia la función abajo. Por ejemplo, para insertar los dos primeros campos sólo, yo haría lo siguiente en Excel y, a continuación, copia los consultas de sql en Mysql.
Code:
=CONCATENAR("INSERT INTO testorders (orderid, customerid) VALUES (";A2;",";B2;")") |
Esto resulta en lo siguiente
Code:
INSERT INTO testorders (orderid, customerid) VALUES (840,25) |
Recuerda, sin embargo, tener cuidado en relación con diferentes tipos de datos; por ejemplo, tendrás que incluir el apóstrofe en la concatenación cuando el campo es del formato varchar.
Encontrar duplicados
By admin on Mar 3, 2009 | In Aprendiz | 4 feedbacks »
Un requisito muy común cuando se trabaja con datos, es encontrar entradas duplicadas. El lenguaje SQL es muy potente en hacerlo, pero mucha gente prefiere utilizar Excel para encontrar duplicados. Mi opinión es que esta es buena para los pequeños conjuntos de datos (menos de 10.000 filas). Puedes utilizar el formato condicional (por ejemplo, con este: =CONTAR.SI(a:A,a2) > 1)), o
puedes utilizar el Filtro/avanzado menú de opciones para filtrar y copiar a otro lugar (hay que activar la casilla para copiar sólo registros únicos). Más modernas versiones de Excel tienen ahora un comando en el menú de Datos: "quitar duplicados"
En MySQL (y, de hecho, otras versiones de SQL) la forma más común de encontrar duplicados de las entradas de campo es el uso de la cláusula GROUP BY. Por ejemplo, para devolver las entradas para el campo "job" de la tabla emp que tienen más de 1 fila/empleado registrado contra ese "job" en particular:
Code:
select job, count(*) | |
-> from emp | |
-> group by job | |
-> having count(*) > 1; |
Si querías devolver registros registró más de 3 veces en la tabla solo necesitas modificar la cláusula HAVING.
Code:
select job, count(*) | |
-> from emp | |
-> group by job | |
-> having count(*) > 3; |
Por cierto, si sólo querías devolver distinta campo(s) en una tabla, puedes utilizar GROUP BY sin realizar suma. Ahora esto es todo muy bien, pero suponiendo que tienes la obligación de devolver todos los campos en un registro se produce cuando el identificador/campo es un duplicado. Podemos hacer esto por un subconsulta de IN:
Code:
mysql> select a.* from emp a | |
-> where a.job in | |
-> (select b.job | |
-> from emp b | |
-> group by b.job having count(*) >1); |
Todo muy bien hasta ahora, pero vamos a introducir una tabla segunda. Supongamos que queremos seleccionar los registros que se producen dos veces en las dos tablas. Podemos hacerlo utilizando el operador UNION para devolver todos los registros de ambas tablas. (recuerde usar UNION ALL, si no los duplicados sería reprimida). Entonces pongamos esto en un "inline view" y, a continuación, utilizar la cláusula GROUP BY para seleccionar sólo duplicados
Code:
select empno, ename, job | |
from | |
(select empno, ename, job | |
from emp | |
UNION ALL | |
select empno, ename, job | |
from emp_temp) as empt | |
group by empno, ename, job having count(*) > 1; |
No estoy seguro de cómo se enfoque en Excel! Aunque es bastante fácil en Mysql!
Diviértete con Mysql!
=====================================
Olivier [Visitor]
Hola!
Excelente artículo la verdad. Y felicidades por el blog.
Estoy interesado en el primer ejemplo. Sabrías cómo eliminar los duplicados encontrados? Es decir, eliminar todos los duplicados encontrados excepto uno. Si se han encontrado 3 filas con un valor igual y 5 con otro valor igual pues eliminar un total de 6 respectivas filas y dejar las 2 originales.
¿Seria muy complicado en mysql? Imagino que a mucha gente lo que le interesa con los duplicados es eliminarlos :-)
Un saludo.
--
Hola Olivier! Gracias por tu pregunta. Me costo un poco en pensar sobre esto.
Es possible eliminar los duplicados bastante facil, con condicion de que haya Primary Key.
Suponer que tenemos estas filas (en la table dup_take)
+-----+-------+----+
| sno | cno | id |
+-----+-------+----+
| 1 | CS112 | 1 |
| 1 | CS113 | 2 |
| 1 | CS114 | 3 |
| 2 | CS114 | 12 |
| 2 | CS112 | 4 |
| 3 | CS112 | 5 |
| 3 | CS114 | 6 |
| 4 | CS113 | 8 |
| 4 | CS112 | 7 |
| 5 | CS113 | 9 |
| 6 | CS113 | 10 |
| 6 | CS114 | 11 |
+-----+-------+----+
Queremos quedar con una fila de cada sno. Bueno, primero hagamos un "temporary table":
create temporary table to_delete (sno tinyint, cno varchar(5), min_id smallint);
Luego podemos insertar estos:
insert into to_delete (sno, min_id)
select sno, MIN(id) from dup_take group by sno having count(*) > 1;
Entonces podemos usar la palabra clave EXISTS (funciona como una prueba de existencia). Es decir, solo eliminar los registros donde "EXISTS" mas de una fila y donde el id no es el original:
delete from dup_take
where exists (
select * from to_delete
where to_delete.sno = dup_take.sno
and to_delete.min_id <> dup_take.id);
Por fin tenemos:
+-----+-------+----+
| sno | cno | id |
+-----+-------+----+
| 1 | CS112 | 1 |
| 2 | CS112 | 4 |
| 3 | CS112 | 5 |
| 4 | CS112 | 7 |
| 5 | CS113 | 9 |
| 6 | CS113 | 10 |
+-----+-------+----+
Saludos
Mark
Potente manipulación de la cadena.
By admin on Feb 7, 2009 | In Aprendiz | Send feedback »
Hola a todos, espero que Mysql en vuestros trabajos u estudios está progresando bien.
En este artículo quiero analizar la manipulación de cadenas de caracteres.
Para empezar voy a mirar la capacidad de moverse a través de una cadena un carácter cada vez.
Me parece que la mejor forma de romper una cadena aparte es el uso de un cartesiano unirse en una tabla que tiene suficiente para unirse a las filas en contra de cada carácter. Así que en mi base de datos me gusta tener una tabla (en este caso llamado pivotnumber) que acaba de un campo llamado id, pobladas con los números ascendente 1, 2, 3, etc. Por ejemplo, si yo quería mostrar un campo de texto en un manera vertical, es que podría utilizar el siguiente código
Code:
mysql> select substr(c.cat,it.pos,1) as L | |
-> from (select cat from categories where cat like 'WORK%') c, | |
-> (select id as pos from pivotnumber) it | |
-> where it.pos <= length(c.cat); | |
+---+ | |
| L | | |
+---+ | |
| W | | |
| o | | |
| r | | |
| k | | |
+---+ | |
4 rows in set |
La cláusula en la línea 4 se asegura de que la unión se lleva a cabo sólo para el mayor número de caracteres en el campo cat. Por supuesto esto es sólo una función estética, pero caminar a través de la cadena puede resultar muy útil si la realización de análisis de datos.
Otra ventaja de utilizar este JOIN de cruce (CROSSJOIN) se puede unirse a imitar dentro de un bucle en sql normal. Solo necesitas limitar por cambiar la cláusula WHERE, indicar cuántos bucles que deseas realizar.
He aquí un interesante uso de este método, que he obtenido de la fantástica SQL Cookbook por Anthony Molinaro. El siguiente código utiliza la función GROUP_CONCAT (Esta función retorna una cadena resultado con valores concatenados de un grupo)junto con el método de cadena de caminar, de poner todos los caracteres dentro de un campo en orden alfabético.
Code:
mysql> select ename, group_concat(c order by c separator '') | |
-> from ( | |
-> select ename, substr(a.ename,it.pos,1) c | |
-> from emp a, | |
-> (select id pos from pivotnumber) it | |
-> where it.pos <= length(a.ename) | |
-> ) x | |
-> group by ename; | |
+---------+-----------------------------------------+ | |
| ename | group_concat(c order by c separator '') | | |
+---------+-----------------------------------------+ | |
| ADAMS | AADMS | | |
| ALLEN | AELLN | | |
| BLAKE | ABEKL | | |
| CLARK | ACKLR | | |
| CLINTON | CILNNOT | | |
| FORD | DFOR | | |
| JAMES | AEJMS | | |
| JONES | EJNOS | | |
| KING | GIKN | | |
| MARTIN | AIMNRT | | |
| SCOTT | COSTT | | |
| SMITH | HIMST | | |
| TURNER | ENRRTU | | |
| WARD | AADDRRWW | | |
+---------+-----------------------------------------+ |
Por último, debo mencionar un par de maneras útiles de manipulación de cadenas, que no requiere los métodos anteriores. A menudo importamos campos que contienen un nombre completo, tal vez en el formato "Apellido, Nombre". Es una cuestión bastante simple para extraer la primera parte es decir, la Apellido hasta el coma. Utilizamos la función LOCATE para encontrar la posición de la primera coma y, a continuación, utilizar la función SUBSTRING de extraer la cadena hasta ese momento.
Code:
mysql> select fullname, | |
-> substring(fullname, 1, LOCATE(',', fullname)-1) as surname | |
-> from people; | |
+-------------------+-----------+ | |
| fullname | surname | | |
+-------------------+-----------+ | |
| Blanco, Martin | Blanco | | |
| Black, Clint | Black | | |
| Lopez, Julia | Lopez | | |
| Zimmerman, Robert | Zimmerman | | |
+-------------------+-----------+ | |
4 rows in set |
Para extraer el primer nombre que se encuentra en el extremo de la cadena, exige un poco más astuto. Encontra la ubicación del espacio antes de la última parte del nombre por la inversión de toda la cadena y el uso de la función LOCATE. A continuación, utiliza este valor en la función RIGHT, que extrae una subcadena de la cadena desde el lado derecho. Como este!
Code:
mysql> select fullname, | |
-> right(fullname, LOCATE(',', REVERSE(fullname)) -2) as FirstName | |
-> from people; | |
+-------------------+-----------+ | |
| fullname | FirstName | | |
+-------------------+-----------+ | |
| Blanco, Martin | Martin | | |
| Black, Clint | Clint | | |
| Lopez, Julia | Julia | | |
| Zimmerman, Robert | Robert | | |
+-------------------+-----------+ | |
4 rows in set |
Por supuesto, puede haber otras complicaciones, pero una combinación de las diversas funciones de cadenas normalmente puede resolver los problemas de datos con nombres.
Para obtener más información, por favor mira la página de documentación Mysql aquí:
mysql manual
Espero haber dado una idea de lo que se puede lograr utilizando funciones de cadenas en MySQL.
Si hay un tema en particular que quieres cubrir en este blog, por favor dejar un pedido en un comentario, y yo haría lo mas posible para obligar.
Hasta la próxima, saludos, y suerte con el código!