2010-08-01 35 views
14

Tengo una tabla con las siguientes columnas:Eliminar duplicados utilizando solo una consulta MySQL?

URL_ID  
URL_ADDR  
URL_Time 

Quiero eliminar duplicados en la columna de la URL_ADDR mediante una consulta MySQL.

¿Es posible hacer algo así sin usar ninguna programación?

+9

SQL está programando ... –

+0

¿Cómo son las URL en URL_ADDR? ¿Todos tienen el mismo formato? es decir: con o sin www. –

+0

no tiene el mismo formato. – Jim

Respuesta

0

Puede agrupar en el URL_ADDR que efectivamente le dará solo valores distintos en el campo URL_ADDR.

select 
URL_ID 
URL_ADDR 
URL_Time 
from 
some_table 
group by 
URL_ADDR 

Enjoy!

+0

Esa consulta no funcionará. –

5

Esto dejará a los que tienen la más alta URL_ID para una determinada URL_ADDR

DELETE FROM table 
WHERE URL_ID NOT IN 
    (SELECT ID FROM 
     (SELECT MAX(URL_ID) AS ID 
     FROM table 
     WHERE URL_ID IS NOT NULL 
     GROUP BY URL_ADDR) X) /*Sounds like you would need to GROUP BY a 
            calculated form - e.g. using REPLACE to 
            strip out www see Daniel's answer*/ 

(La tabla derivada 'X' es avoid the error "No se puede especificar la tabla de destino 'nombreTabla' para la actualización de cláusula ")

+0

@Vilx: Es por eso que lo entierras en otra subconsulta. –

3

Bueno, siempre se puede:

  1. crear una tabla temporal;
  2. INSERT INTO ... SELECT DISTINCT en la tabla temporal de la tabla original;
  3. clara tabla original
  4. INSERT INTO ... SELECT en la tabla original de la tabla temporal
  5. plataforma de descenso de temperatura.

Es torpe y torpe, y requiere varias consultas (sin mencionar privilegios), pero servirá de mucho si no encuentra otra solución.

30

Consideremos el siguiente caso de prueba:

CREATE TABLE mytb (url_id int, url_addr varchar(100)); 

INSERT INTO mytb VALUES (1, 'www.google.com'); 
INSERT INTO mytb VALUES (2, 'www.microsoft.com'); 
INSERT INTO mytb VALUES (3, 'www.apple.com'); 
INSERT INTO mytb VALUES (4, 'www.google.com'); 
INSERT INTO mytb VALUES (5, 'www.cnn.com'); 
INSERT INTO mytb VALUES (6, 'www.apple.com'); 

Cuando nuestra tabla de prueba ahora contiene:

SELECT * FROM mytb; 
+--------+-------------------+ 
| url_id | url_addr   | 
+--------+-------------------+ 
|  1 | www.google.com | 
|  2 | www.microsoft.com | 
|  3 | www.apple.com  | 
|  4 | www.google.com | 
|  5 | www.cnn.com  | 
|  6 | www.apple.com  | 
+--------+-------------------+ 
5 rows in set (0.00 sec) 

entonces podemos usar la sintaxis de varias tablas DELETE de la siguiente manera:

DELETE t2 
FROM mytb t1 
JOIN mytb t2 ON (t2.url_addr = t1.url_addr AND t2.url_id > t1.url_id); 

... lo que eliminará las entradas duplicadas, dejando sólo la primera URL basado en url_id:

SELECT * FROM mytb; 
+--------+-------------------+ 
| url_id | url_addr   | 
+--------+-------------------+ 
|  1 | www.google.com | 
|  2 | www.microsoft.com | 
|  3 | www.apple.com  | 
|  5 | www.cnn.com  | 
+--------+-------------------+ 
3 rows in set (0.00 sec) 

ACTUALIZACIÓN - En relación con los nuevos comentarios anteriores:

Si las URL duplicadas no lo hará tienen el mismo formato, es posible que desee aplicar la función REPLACE() para eliminar www. o http:// partes.Por ejemplo:

DELETE t2 
FROM mytb t1 
JOIN mytb t2 ON (REPLACE(t2.url_addr, 'www.', '') = 
        REPLACE(t1.url_addr, 'www.', '') AND 
        t2.url_id > t1.url_id); 
+0

Entonces, ¿JOIN no activará el error 1093? De acuerdo, una JOIN no es una subconsulta, pero ser el autorreferencial es el verdadero problema ... –

+0

@OMG: Parece que no :) –

+0

+1 Para cubrir el problema 'REPLACE'. –

0

Esto funcionará siempre y cuando su columna URL_ID es único.

DELETE FROM url WHERE URL_ID IN (
SELECT URL_ID 
FROM url a INNER JOIN (
    SELECT URL_ADDR, MAX(URL_ID) MaxURLId 
    FROM url 
    GROUP BY URL_ADDR 
    HAVING COUNT(*) > 1) b ON a.URL_ID <> b.MaxURLId AND a.URL_ADDR = b.URL_ADDR 
) 
1

Daniel Vassallo ¿Cómo hacer para una columna múltiple?

DELETE t2 FROM t1 directory1 JOIN t2 directory1 ON (t2.page = t1.page, t2.parentTopic = t1.parentTopic, t2.title = t1.title, t2.description = t1.description, t2. linktype = t1.linktype, t2.priority = t1.priority AND t2.linkID> t1.linkID);

tal como esto?

Cuestiones relacionadas