2010-11-25 16 views
5

He tabla siguiente:SELECT DISTINCT para grupos de datos

etc. En otras palabras, I tienen grupos de datos por ID. Notará que el grupo de datos (A, B) ocurre varias veces. Quiero una consulta que puede identificar los grupos de datos distintas y número de ellos, tales como:

DataID  Data 
101  A 
102  A 
102  B 
103  C 
104  D 

Así ID de datos 102 se parecería a los datos (A, B), ID de datos 103 se asemejaría datos (C), etc. Con el fin para poder reescribir mi tabla original de esta forma:

ID DataID 
1 101 
2 102 
3 102 
4 103 
5 104 
6 102 

¿Cómo puedo hacer eso?


PS. Código para generar la primera tabla:

CREATE TABLE #t1 (id INT, data VARCHAR(10)) 
INSERT INTO #t1 
SELECT 1, 'A' 
UNION ALL SELECT 2, 'A' 
UNION ALL SELECT 2, 'B' 
UNION ALL SELECT 3, 'A' 
UNION ALL SELECT 3, 'B' 
UNION ALL SELECT 4, 'C' 
UNION ALL SELECT 5, 'D' 
UNION ALL SELECT 6, 'A' 
UNION ALL SELECT 6, 'B' 
+0

@littlegreen - ¿Cuál es la base de su fila 3 2 en su salida esperada? –

+1

Estoy luchando por ver lo que quiere decir/requiere. ¿Cómo se relacionan ID y DataID (si es que lo están)?¿Hay alguna posibilidad de que pueda volver a trabajar el ejemplo de modo que no haya valores reutilizados entre tablas a menos que se refieran a la misma cosa? –

+0

Porque ID 3 tiene datos (A, B) en mi tabla original, y esa combinación de datos ha recibido DataID 2. – thomaspaulb

Respuesta

3

En mi opinión Tienes que crear un agregado personalizado que concatena datos (en caso de las cadenas enfoque CLR se recomienda por razones de Potencia). Luego, agrupe por ID y seleccione distinto de la agrupación, agregue una función row_number() o agregue un dense_rank() a su elección. De todos modos, debería verse así

with groupings as (
select concat(data) groups 
from Table1 
group by ID 
) 
select groups, rownumber() over() from groupings 
+0

Eso es exactamente lo que esperaba evitar ... (el concat) – thomaspaulb

+0

Desafortunadamente esa es probablemente la solución. ¿Cómo se pueden distinguir diferentes grupos de datos de otra manera que crear algún rey de agregado (resumen para cada ID) y compararlo con otros? Por qué la solución global no es viable para usted. ¿Las cadenas son largas o los datos son una especie de archivo BitMap oor? – luckyluke

+0

Las cadenas son bastante largas. Les asigné una identificación entera, pero concatenar estos enteros en una cadena y distinguirlos para este propósito me parece un feo truco. Podría ser la única solución, sí, pero quería verificar aquí antes de implementarlo. – thomaspaulb

2

La siguiente consulta con CASE le dará el resultado que se muestra a continuación.

A partir de ahí, obtener los distintos grupos de datos y seguir adelante no debería ser realmente un problema.

SELECT  
    id, 
    MAX(CASE data WHEN 'A' THEN data ELSE '' END) + 
    MAX(CASE data WHEN 'B' THEN data ELSE '' END) + 
    MAX(CASE data WHEN 'C' THEN data ELSE '' END) + 
    MAX(CASE data WHEN 'D' THEN data ELSE '' END) AS DataGroups 
FROM t1 
GROUP BY id 

ID DataGroups 
1 A 
2 AB 
3 AB 
4 C 
5 D 
6 AB 

Sin embargo, este tipo de lógica sólo funcionará en caso de que los valores de "datos" son tanto fijos y conocidos de antemano.

En su caso, usted dice que es el caso. Sin embargo, teniendo en cuenta que también dice que son 1000 de ellos, esto será francamente una consulta de aspecto ridículo :-)

La sugerencia de LuckyLuke anterior sería, francamente, la forma más genérica y probablemente sea más sensata. acerca de implementar la solución, aunque en su caso.

+0

Estoy de acuerdo. Pero gracias por la respuesta :-) – thomaspaulb

0

De los datos de la muestra (después de haber añadido la falta 2, 'A' tupla, A continuación se presenta la nueva numeración (y uniqueified) de datos:

with NonDups as (
select t1.id 
from #t1 t1 left join #t1 t2 
on t1.id > t2.id and t1.data = t2.data 
group by t1.id 
having COUNT(t1.data) > COUNT(t2.data) 
), DataAddedBack as (
    select ID,data 
    from #t1 where id in (select id from NonDups) 
), Renumbered as (
    select DENSE_RANK() OVER (ORDER BY id) as ID,Data from DataAddedBack 
) 
select * from Renumbered 

El dar:

1   A 
2   A 
2   B 
3   C 
4   D 

creo que entonces , que es una cuestión de la división de relación para hacer coincidir las filas de esta salida con las filas de la tabla original

0

sólo para compartir mi propia solución sucia que estoy usando por el momento:.

SELECT DISTINCT t1.id, D.data 
FROM #t1 t1 
CROSS APPLY ( 
    SELECT CAST(Data AS VARCHAR) + ',' 
    FROM #t1 t2 
    WHERE t2.id = t1.id 
    ORDER BY Data ASC 
    FOR XML PATH('')) 
D (Data) 

Y luego va analógico a la solución de LuckyLuke.

Cuestiones relacionadas