2010-02-01 14 views
34

Devo recuperare la prima riga in cima a ogni serie di record duplicati dalla tabella riportata di seguito. Ho bisogno di usare questa query in vistaOttieni il primo record più alto da record duplicati senza identità univoca

per favore nessuna tabella temporanea come ho già fatto aggiungendo colonna identità e funzione min e gruppo per. Ho bisogno di una soluzione senza tabella temporanea o variabile di tabella

Questo è solo dati di esempio. Originale ha 1000s di record nella tabella e ho bisogno solo risultato da Top 1000 quindi non è possibile utilizzare distinta

Sto usando 2005

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

Grazie SQL Server.

+11

+1 per prendere tutto il tempo necessario per eseguire l'intero mockup dello schermo! Vorrei che più persone mettessero tanto impegno nelle loro domande. – Aaronaught

+0

Il collegamento dell'immagine è morto. :/ –

risposta

6

La risposta dipende specificamente da cosa intendi per i "primi 1000 distinti" record.

Se vuoi dire che si desidera tornare al massimo 1000 record distinti, indipendentemente dal numero di duplicati sono nella tabella, quindi scrivere questo:

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

Se si desidera solo ricerca i primi 1000 righe della tabella, e potenzialmente ritorno molto meno di 1000 righe distinte, allora si può scrivere con una sottoquery o CTE, in questo modo:

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

il ORDER BY è naturalmente facoltativa se si don' t cura di quali record torni.

1

non SELECT DISTINCT aiuto? Suppongo che restituirebbe il risultato desiderato.

+1

+1 Corretto, per ottenere l'output richiesto per input dato :-) – gbn

+0

Mi spiace di non averlo menzionato nella mia domanda Questo è solo un esempio di dati. L'originale ha 1000 di record in tabella e ho bisogno solo di un risultato tra i primi 1000 quindi non posso usare ** distinto ** – Kashif

1

Usando DISTINCT dovrebbe farlo:

SELECT DISTINCT id, uname, tel 
FROM YourTable 

Anche se si potrebbe davvero fare con l'avere una chiave primaria su quel tavolo, un modo per identificare in modo univoco ogni record. Staremmo pensando di incollare una colonna IDENTITY sul tavolo

+0

Mi spiace di non averlo menzionato nella mia domanda Questo è solo un esempio di dati. L'originale ha 1000 di record in tabella e ho bisogno solo di un risultato tra i primi 1000 quindi non posso usare ** distinto ** – Kashif

1

La soluzione migliore è quella di correggere il progetto del datbase e aggiungere la colonna identioty alla tabella. Perché hai un tavolo senza uno in primo luogo? Soprattutto uno con record duplicati! Chiaramente il database stesso ha bisogno di riprogettazione.

E perché è necessario avere questo in una vista, perché la soluzione con la tabella temporanea non è una soluzione valida? Le viste non sono di solito una buona cosa da fare in un database perfettamente bello.

+0

Hai ragione MA per favore dimmi 1) come posso convincere il mio manager che ha bisogno di questa soluzione in Visualizza. 2) Ho ricevuto il db design dal client e DEVO attenermi a questo design. – Kashif

1

si può provare il seguente:

  1. creare una vista che seleziona semplicemente tutte le colonne della tabella originale, ma aggiungere una colonna numerica in più che aumentano di valore con ogni record \ fila. Potrebbe essere necessario rendere questa colonna una colonna non intera (ad esempio un decimale e incrementarla di 1,00 per ogni record per utilizzarla nell'istruzione SQL RANK()).

  2. Aggiungete inoltre un'altra colonna (ad esempio "RecordRank") per contenere i valori di classificazione calcolati per tutte le colonne utilizzando la clausola RANK() OVER SQL per creare valori per questa colonna - vedere i riferimenti di seguito.L'istruzione RANK consente di partizionare i record e quindi ordinare ogni record di partizione in base ai valori nell'ordine per colonna (utilizzare il Colonna con valori crescenti dal passaggio 1 per il proprio ordine). Si utilizzano le colonne con dati identici nella clausola di partizione in modo che tutti questi duplicati simili siano partizionati o raggruppati e quindi ordinati dai valori nella colonna aggiuntiva (ordine per colonna del passaggio 1).

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

3, Dopo aver creato con successo la vista sopra, basta scrivere un altro al fine di selezionare solo i record con 'RecordRank' = 1

Questo dovrebbe selezionare solo uno di ogni record dai duplicati o partizioni.

Spero che questo aiuti - Malcom Sankoh

11

Trova tutti i prodotti che è stato ordinato 1 o più volte ... (tipo di record duplicati)

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

Per selezionare l'ultimo inserito di quelli .. .

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

Questa dovrebbe essere la risposta corretta accettata – Fandango68

1

Qui ci sono due soluzioni, io sto usando server Oracle SQL:

1) utilizzando oltre clausola:

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) Uso di sub-query:

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 volte è possibile utilizzare l'operatore CROSS APPLY in questo modo:

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

In questa query I è necessario scegliere solo il primo dei tanti duplicati che si verificano naturalmente nei miei dati. Funziona su database SQL Server 2005+.

+2

Questo funziona come un fascino! – MJ33

+0

Grazie. questo ha risolto un problema ricorrente piuttosto grande che abbiamo avuto con dati duplicati. – NotMe

Problemi correlati