tipos subconsultas resueltos inner ejercicios ejemplos datos consultas avanzadas agrupadas sql performance sqlite duplicates correlated-subquery

subconsultas - subquery sql server ejemplos



SQL: conteo y numeración de duplicados: optimización de la subconsulta correlacionada (1)

Una auto unión puede ser más rápida que una subconsulta correlacionada

SELECT d1.id, d1.match1, d1.match2, d1.match3, d1.data, count(*) matchid FROM idcountdata d1 JOIN idcountdata d2 on d1.match1 = d2.match1 and d1.match2 = d2.match2 and d1.match3 = d2.match3 and d1.id >= d2.id GROUP BY d1.id, d1.match1, d1.match2, d1.match3, d1.data

Esta consulta puede aprovechar un índice compuesto en (match1,match2,match3,id)

En una base de datos SQLite tengo una tabla donde necesito contar los duplicados en ciertas columnas (es decir, filas donde 3 columnas particulares son las mismas) y luego también numere cada uno de estos casos (es decir, si hay 2 ocurrencias de un duplicado particular, necesita ser numerado como 1 y 2). Me resulta un poco difícil de explicar con palabras, así que usaré un ejemplo simplificado a continuación.

Los datos que tengo son similares a los siguientes (la primera línea es la fila del encabezado, a la tabla se hace referencia en los siguientes como "idcountdata"):

id match1 match2 match3 data 1 AbCde BC 0 data01 2 AbCde BC 0 data02 3 AbCde BC 1 data03 4 AbCde AB 0 data04 5 FGhiJ BC 0 data05 6 FGhiJ AB 0 data06 7 FGhiJ BC 1 data07 8 FGhiJ BC 1 data08 9 FGhiJ BC 2 data09 10 HkLMop BC 1 data10 11 HkLMop BC 1 data11 12 HkLMop BC 1 data12 13 HkLMop DE 1 data13 14 HkLMop DE 2 data14 15 HkLMop DE 2 data15 16 HkLMop DE 2 data16 17 HkLMop DE 2 data17

Y la salida que necesito generar para lo anterior sería:

id match1 match2 match3 data matchid matchcount 1 AbCde BC 0 data01 1 2 2 AbCde BC 0 data02 2 2 3 AbCde BC 1 data03 1 1 4 AbCde AB 0 data04 1 1 5 FGhiJ BC 0 data05 1 1 6 FGhiJ AB 0 data06 1 1 7 FGhiJ BC 1 data07 1 2 8 FGhiJ BC 1 data08 2 2 9 FGhiJ BC 2 data09 1 1 10 HkLMop BC 1 data10 1 3 11 HkLMop BC 1 data11 2 3 12 HkLMop BC 1 data12 3 3 13 HkLMop DE 1 data13 1 1 14 HkLMop DE 2 data14 1 4 15 HkLMop DE 2 data15 2 4 16 HkLMop DE 2 data16 3 4 17 HkLMop DE 2 data17 4 4

Anteriormente estaba usando un par de subconsultas correlacionadas para lograr esto de la siguiente manera:

SELECT id, match1, match2, match3, data, (SELECT count(*) FROM idcountdata d2 WHERE d1.match1=d2.match1 AND d1.match2=d2.match2 AND d1.match3=d2.match3 AND d2.id<=d1.id) AS matchid, (SELECT count(*) FROM idcountdata d2 WHERE d1.match1=d2.match1 AND d1.match2=d2.match2 AND d1.match3=d2.match3) AS matchcount FROM idcountdata d1;

Pero la tabla tiene más de 200,000 filas (y los datos pueden ser variables en longitud / contenido) y, por lo tanto, esto toma horas para ejecutarse. (Extrañamente, cuando utilicé por primera vez la misma consulta sobre los mismos datos en el período de mediados a finales de 2013, tardé minutos en lugar de horas, pero eso no viene al caso, incluso en aquel momento pensé que era poco elegante e ineficiente).

Ya he convertido la subconsulta correlacionada para "recuento de coincidencias" en el anterior a una subconsulta no correlacionada con un JOIN de la siguiente manera:

SELECT d1.id, d1.match1, d1.match2, d1.match3, d1.data, matchcount FROM idcountdata d1 JOIN (SELECT id,match1,match2,match3,count(*) matchcount FROM idcountdata GROUP BY match1,match2,match3) d2 ON (d1.match1=d2.match1 and d1.match2=d2.match2 and d1.match3=d2.match3);

Por lo tanto, es solo la subconsulta de "coincidencia" que me gustaría obtener ayuda para optimizar.
En resumen, la siguiente consulta se ejecuta muy lentamente para conjuntos de datos más grandes:

SELECT id, match1, match2, match3, data, (SELECT count(*) FROM idcountdata d2 WHERE d1.match1=d2.match1 AND d1.match2=d2.match2 AND d1.match3=d2.match3 AND d2.id<=d1.id) matchid FROM idcountdata d1;

¿Cómo puedo mejorar el rendimiento de la consulta anterior?
No tiene que ejecutarse en segundos, pero debe ser de minutos en lugar de horas (para alrededor de 200,000 filas).