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?
3 Réponses :
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
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)
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);
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.
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?