1
votes

Historique de nettoyage SQL valeurs intermédiaires répétées

J'ai remarqué que ma table a plusieurs valeurs redondantes qui doivent être nettoyées, c'est une table qui enregistre les changements de prix, je voudrais donc nettoyer de la manière suivante:

product | price | date
------------------------
1       | 1     | 1
2       | 77    | 5
1       | 2     | 7
1       | 1     | 9
1       | 3     | 13

À ceci :

product | price | date
------------------------
1       | 1     | 1
1       | 1     | 2
1       | 1     | 3
1       | 1     | 4
2       | 77    | 5
1       | 1     | 6
1       | 2     | 7
1       | 2     | 8
1       | 1     | 9
1       | 1     | 10
1       | 1     | 11
1       | 1     | 12
1       | 3     | 13

Supposons également que dans ce cas, la colonne id est la même que date .

SELECT DISTINCT ON (produit, prix)

ne fonctionnera pas car cela ignorerait le changement de produit 1 le jour 9 ou 1 , Le problème est que je souhaite regrouper par produit , prix mais seulement à certains intervalles selon les changements pertinents par date .

Même s'il est possible de commander le produit , il est difficile d'ignorer l'ordre de changement de date et de prix .

L'objectif est de supprimer tous les identifiants qui ne sont pas dans le tableau de résultats prévu.

Quelqu'un a-t-il des suggestions?


2 commentaires

Quel produit de SGBD utilisez-vous? "SQL" n'est qu'un langage de requête, pas le nom d'un produit de base de données spécifique. Veuillez ajouter une balise pour le produit de base de données que vous utilisez. Pourquoi devrais-je marquer mon SGBD distinct on () suggère que vous utilisez Postgres?


Qu'est-il arrivé à 1/6 dans vos résultats?


3 Réponses :


2
votes

Il s'agit d'un problème de lacunes et d'îlots, où vous souhaitez regrouper des lignes adjacentes du même produit ayant le même prix.

Voici une approche utilisant la différence entre les numéros de ligne pour définir les groupes p >

product | price | date
------: | ----: | ---:
      1 |     1 |    1
      2 |    77 |    5
      1 |     2 |    7
      1 |     1 |    9
      1 |     3 |   13

Démo sur DB Fiddle :

select product, price, min(date) date
from (
    select 
        t.*,
        row_number() over(partition by product order by date) rn1,
        row_number() over(partition by product, price order by date) rn2
    from mytable t
) t
group by product, price, rn1 - rn2
order by min(date)


0 commentaires

0
votes

Supprimez les lignes en double en conservant (utilisez min () ou max () pour conserver la ligne la plus ancienne / la plus récente)

vous pouvez filtrer les colonnes qui doivent déterminer les doublons en les regroupant

DELETE FROM MyTable WHERE RowId NOT IN (SELECT MIN(RowId) FROM MyTable GROUP BY Col1, Col2, Col3);


0 commentaires

0
votes

Vous semblez vouloir la première ligne lorsque le prix change. Si tel est le cas, je recommande lag():

select t.product, t.product, t.price
from (select t.*,
             lag(price) over (partition by product order by date) as prev_price
      from t
     ) t
where prev_price is null or prev_price <> price;

Aucune agrégation n'est nécessaire. Cette solution doit être qu'une solution utilisant l'agrégation ainsi que les fonctions de fenêtre.


0 commentaires