2010-02-01 14 views
34

Necesito buscar la primera fila superior de cada conjunto duplicado de registros de la tabla que figura a continuación. Necesito usar esta consulta en la vistaObtener el primer registro superior de los registros duplicados que no tienen identidad única

por favor, no hay tabla temporal ya que lo he hecho agregando la columna de identidad y la función min y agrupar. Necesito una solución sin tabla temporal o variable de tabla

Esto es solo un ejemplo de datos. Original tiene 1000 de los registros de la tabla y necesito resultado justo desde la parte superior 1000 por lo que no se puede utilizar distinta

estoy usando SQL Server 2005

alt text http://img686.imageshack.us/img686/42/duplicate.png

Gracias.

+11

+1 por tomarse todo el tiempo para hacer la maqueta de la pantalla completa! Deseo que más personas pongan tanto esfuerzo en sus preguntas. – Aaronaught

+0

Su enlace de imagen está muerto. :/ –

Respuesta

6

La respuesta depende específicamente de lo que quiere decir con los "1000 registros principales distintos".

Si quiere decir que desea volver a la mayoría de los 1000 registros distintos, independientemente del número de duplicados se encuentran en la tabla, a continuación, escribir lo siguiente:

SELECT DISTINCT TOP 1000 id, uname, tel 
FROM Users 
ORDER BY <sort_columns> 

Si sólo desea búsqueda los primeros 1000 filas de la tabla, y potencialmente vuelven mucho menos de 1000 filas distintas, a continuación, se escribirían con una subconsulta o CTE, así:

SELECT DISTINCT * 
FROM 
(
    SELECT TOP 1000 id, uname, tel 
    FROM Users 
    ORDER BY <sort_columns> 
) u 

el ORDER BY es, por supuesto opcional si usted don' No importa qué registros registres.

1

¿No es SELECT DISTINCT ayuda? Supongo que devolverá el resultado que desea.

+1

+1 Correcto, para obtener la salida requerida para la entrada dada :-) – gbn

+0

Lo siento, no lo mencioné en mi pregunta. Esto es solo datos de muestra. Original tiene 1000s de registros en la tabla y solo necesito el resultado de los 1000 principales, así que no puedo usar ** distinct ** – Kashif

1

Usando DISTINCT debe hacerlo:

SELECT DISTINCT id, uname, tel 
FROM YourTable 

Aunque se podía realmente ver con tener una clave principal en esa mesa, una manera de identificar de forma única cada registro. Consideraría incluir una columna de IDENTIDAD en la tabla

+0

Lo siento, no lo mencioné en mi pregunta. Esto es solo muestra de datos. Original tiene 1000s de registros en la tabla y solo necesito el resultado de los 1000 principales, así que no puedo usar ** distinct ** – Kashif

1

Su mejor opción es arreglar el diseño de la base de datos y agregar la columna de identificación a la tabla. ¿Por qué tienes una mesa sin una en primer lugar? ¡Especialmente uno con registros duplicados! Claramente, la base de datos en sí necesita un rediseño.

¿Y por qué tiene que tener esto en una vista, por qué su solución con la tabla temporal no es una solución válida? Por lo general, las vistas no son muy buenas para hacer en una base de datos perfecta.

+0

Tienes razón PERO por favor dime 1) cómo puedo convencer a mi gerente que necesita esta solución en View. 2) Obtuve el diseño de DB del cliente y TENGO que seguir con este diseño. – Kashif

1

Usted puede intentar lo siguiente:

  1. crear una vista que sólo tiene que seleccionar todas las columnas de la tabla original, pero añadir una columna adicional numérico que aumentan en valor con cada registro \ fila. Es posible que necesite convertir esta columna en una columna no entera (por ejemplo, un decimal e incrementarla en 1,00 para que cada registro lo use en la instrucción SQL RANK()).

  2. También agregue otra columna (por ejemplo, 'RecordRank') para contener los valores calificados calculados para todas las columnas que usan la cláusula RANK() OVER SQL para crear valores para esta columna; consulte las referencias a continuación.La instrucción RANK le permite particionar los registros y luego ordenar cada registro de partición de acuerdo con los valores en el orden por columna (use la columna con valores crecientes del paso 1 para su orden). Utiliza las columnas con datos idénticos en la cláusula de partición para que todos los duplicados similares se particionen o se agrupen, y luego se ordenen por los valores en la columna adicional (orden por columna desde el paso 1).

    http://msdn.microsoft.com/en-us/library/ms189461.aspx

3, Después de crear con éxito el punto de vista anterior, acaba de escribir otra vista para seleccionar sólo los registros con 'RecordRank' = 1

Esto debe seleccionar sólo una de cada registro de los duplicados o particiones.

Espero que esto ayude - Malcom Sankoh

11

Encuentra todos los productos que han sido ordenados 1 o más veces ... (tipo de registros duplicados)

SELECT DISTINCT * from [order_items] where productid in 
(SELECT productid 
    FROM [order_items] 
    group by productid 
    having COUNT(*)>0) 
order by productid 

Para seleccionar la última insertada de los .. .

SELECT DISTINCT productid, MAX(id) OVER (PARTITION BY productid) AS LastRowId from [order_items] where productid in 
(SELECT productid 
    FROM [order_items] 
    group by productid 
    having COUNT(*)>0) 
order by productid 
+2

Esta debería haber sido la respuesta correcta aceptada – Fandango68

1

Aquí hay dos soluciones, que estoy utilizando el servidor Oracle SQL:

1) el uso de más de cláusula:

with org_table as 
(select 1 id, 'Ali' uname 
    from dual 
    union 
    select 1, 'June' 
    from dual 
    union 
    select 2, 'Jame' 
    from dual 
    union 
    select 2, 'July' from dual) 
select id, uname 
    from (select a.id, 
       a.uname, 
       ROW_NUMBER() OVER(PARTITION BY a.id ORDER BY a.id) AS freq 

      from org_table a) 
where freq = 1 

2) El uso de sub-consulta:

with org_table as 
(select 1 id, 'Ali' uname 
    from dual 
    union 
    select 1, 'June' 
    from dual 
    union 
    select 2, 'Jame' 
    from dual 
    union 
    select 2, 'July' from dual) 

select a.id, 
     (select b.uname 
      from org_table b 
     where b.id = a.id 
      and rownum = 1) 
    from (select distinct id from org_table) a 
6

A veces se puede utilizar el operador CROSS APPLY así:

select distinct result.* from data d 
cross apply (select top 1 * from data where data.Id = d.Id) result 

En esta consulta I Necesito elegir solo el primero de muchos duplicados que naturalmente ocurren en mis datos. Funciona en bases de datos SQL Server 2005+.

+2

¡Esto funciona como un encanto! – MJ33

+0

Gracias. esto resolvió un gran problema recurrente que hemos tenido con los datos duplicados. – NotMe

Cuestiones relacionadas