2017-02-08 1 views
1

Disons que nous avons le tableau suivantlignes SELECT basées sur le caractère distinctif de deux colonnes

orderId productId orderDate    amount  
1  2   2017-01-01 20:00:00 10 
1  2   2017-01-01 20:00:01 10 
1  3   2017-01-01 20:30:10 5 
1  4   2017-01-01 22:31:10 1  

où les 2 premiers rangs sont connus pour être des doublons (par exemple, résultat d'un logiciel défectueux), parce que orderId + productId doit former une clé unique

Je souhaite supprimer ce type de doublons. Comment faire cela de la manière la plus efficace?

S'il n'y avait pas la ORDERDATE une seconde différence, nous pourrions utiliser

SELECT DISTINCT * FROM `table` 

Avec la différence, on pourrait utiliser groupby:

SELECT `orderId`,`productId`,MIN(`orderDate`),MIN(`amount`) 
FROM table 
GROUP BY `orderId`,`productCode` 

Je trouve cette dernière commande très fatigant de taper s'il y a beaucoup de colonnes. Quelles sont les autres options?

MISE À JOUR: J'utilise Snowflake.

+2

Quel SGBD utilisez-vous? –

+1

Que faire si le montant diffère? Comment décider laquelle des deux entrées conserver? –

+1

Voulez-vous supprimer les enregistrements en double de la table ou ne pas les sélectionner? –

Répondre

1

Si votre DBMS prend en charge la fonction de fenêtre ROW_NUMBER puis

select * from 
(
select row_number()Over(Partition by orderId,productId order by orderDate asc) as rn,* 
From yourtable 
)a 
Where Rn = 1 
+0

On dirait que OP utilise MySQL. – jarlh

+0

@jarlh: au moins MariaDB est sur le point d'arriver au 21ème siècle: https://mariadb.com/kb/fr/mariadb/mariadb-1020-release-notes/ –

+0

@jarlh - Vrai .. n'a pas vu le dos ticks –

0

Vous pouvez utiliser NOT EXISTS pour exclure les enregistrements qui ont une meilleure correspondance:

select * from mytable 
where not exists 
(
    select * 
    from mytable other 
    where other.orderid = mytable.orderid 
    and other.productid = mytable.productid 
    and other.orderdate < mytable.orderdate 
); 
0

Cela semble que si vous voulez obtenir les enregistrements avec la valeur minimale orderdate dans les enregistrements avec orderid et productid communs. Cela peut être exprimé en SQL comme suit:

select * from mytable t where t.orderdate = 
    (select min(t2.orderdate) 
    from mytable t2 
    where t2.orderid = t.orderid 
    and t2.productid = t.productid); 

Notez que cette requête ne peut pas éliminer les doublons exacts dans les colonnes orderid, productid et orderdate; mais cela n'a pas été demandé.