2
votes

Comment obtenir des enregistrements consécutifs ayant la même valeur en SQL

Disons que j'ai une table comme ci-dessous, comment puis-je obtenir que tous les enregistrements aient le même account_id, triés par begin_date, et que les enregistrements consécutifs aient la même valeur

WITH Ordered AS (
            SELECT *,  ROW_NUMBER() OVER (ORDER BY account_id, begin_date, value) AS order_id
            FROM addresses)
SELECT o1.account_id, o1.value
FROM Ordered o1
    INNER JOIN Ordered o2 ON o2.account_id == o1.account_id AND o2.value = o1.value AND s2.order_id = s1.order_id + 1
UNION
SELECT o2.account_id, o2.value 
FROM Ordered o1
    INNER JOIN Ordered o2 ON o2.account_id == o1.account_id AND o2.value = o1.value AND s2.order_id = s1.order_id + 1
order by
        1,2;

Dans ce cas, les éléments suivants doivent être renvoyés :

begin_date       value    account_id   other
20180701    1013        222         11
20180702    1013        222         11
20180701    1022        222         12
20180702    1022        222         12
20180701    1024        111         13
20180702    1024        111         13

J'ai essayé d'utiliser le mot clé "WITH", mais ressemble à ce n'est plus valide , voici ce que j'ai écrit:

begin_date       value    account_id   other
20180701    1013        222         11
20180702    1013        222         11
20180701    1022        222         12
20180702    1022        222         12
20180703    1023        222         12
20180701    1024        111         13
20180702    1024        111         13 


5 commentaires

montrez-nous votre requête. WITH est valide sur mysql uniquement sur v8 +


expliquer la logique. pourquoi 20180703 est supprimé?


merci, mis à jour. Valeur de 20180703 1023 qui n'est pas la même que la valeur de 20180702 précédente


Expliquez à nouveau la logique et montrez-nous quelle erreur vous avez.


@ user8142520. . . Veuillez définir «enregistrements consécutifs». Les tables SQL représentent des ensembles non ordonnés . Il n'y a pas de classement sauf si une colonne spécifie cet ordre. Aucune colonne de commande de ce type n'est évidente.


3 Réponses :


0
votes

celui-ci devrait fonctionner pour vous

select
    x.*
from
    <table_name> as x
    join (  select
                value,
                account_id,
                other
            from
                <table_name>
            group by
                value,
                account_id,
                other
            having
                count(*) > 1) as y on   x.value = y.value
                                        and x.account_id = y.account_id
                                        and x.other = y.other


0 commentaires

0
votes

Utilisez lead () et lag():

select t.*
from (select t.*, 
             lag(value) over (partition by account_id, other order by begin_date) as prev_value,
             lead(value) over (partition by account_id, other order by begin_date) as next_value
      from t
     ) t
where value in (prev_value, next_value);


0 commentaires

0
votes

Si la version de votre serveur MySQL est inférieure à 8, essayez ceci:

| begin_date | value | account_id | other |
+------------+-------+------------+-------+
| 2018-07-01 |  1013 |        222 |    11 |
| 2018-07-02 |  1013 |        222 |    11 |
| 2018-07-01 |  1022 |        222 |    12 |
| 2018-07-02 |  1022 |        222 |    12 |
| 2018-07-01 |  1024 |        111 |    13 |
| 2018-07-02 |  1024 |        111 |    13 |

Sortie:

select a.*
from data a
where exists(
  select *
  from data b
  where b.account_id = a.account_id and
        b.value = a.value and
        b.begin_date in (a.begin_date + interval 1 day,
                         a.begin_date - interval 1 day)
);

Testez-le en ligne avec sqlfiddle.com .


0 commentaires