Création lignes SQL avec SED, AWK ou autre.

Résolu
pcsystemd Messages postés 734 Statut Membre -  
mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   -

Bonjour,

J'ai un fichier avec des ID comme suite :

6728111836
6728155980
6728509182
6728140429
6728316021
6728388875
6728344022
6728463975
etc..

Pour chaque ID, j'ai besoin de construire les 4 lignes pour postgresql suivantes mais avec les contraintes suivantes :

- La valeur totale des 4 lignes pour le champ "vate=100" doit être égale à 100. Dans l'exemple ci-dessous (6.7 + 10 + 20.52 + 62.78 = 100)


- La valeur du champ "vate" doit aller du plus petit montant au plus grand comme l'exemple ci-dessous. On voit que la valeur de la ligne ayant le champ "r_scard_ind=39" est plus petit que la seconde ligne ayant le champ "r_scard_ind=37" qui elle même est plus petit que la troisieme ligne ayant le champ "r_scard_ind=33" et enfin la quatrieme ligne ayant le champ "r_scard_ind=35" doit avoir le montant dans le champ "vate" le plus élevé

Pour l'ID 6728111836 (6.7 + 10 + 20.52 + 62.78 = 100)

update scard_vate set vate='6.7' where r_scard_ind=39 and r_scard_se_wb=6728111836;
update scard_vate set vate='10' where r_scard_ind=37 and r_scard_se_wb=6728111836;
update scard_vate set vate='20.52' where r_scard_ind=33 and r_scard_se_wb=6728111836;
update scard_vate set vate='62.78' where r_scard_ind=35 and r_scard_se_wb=6728111836;

Pour l'ID 6728155980  (8.2 + 9.6 + 21.3 + 60.9 = 100)

update scard_vate set vate='8.2' where r_scard_ind=39 and r_scard_se_wb=6728155980;
update scard_vate set vate='9.6' where r_scard_ind=37 and r_scard_se_wb=6728155980;
update scard_vate set vate='21.3' where r_scard_ind=33 and r_scard_se_wb=6728155980;
update scard_vate set vate='60.9' where r_scard_ind=35 and r_scard_se_wb=6728155980;

etc..

Un possibilité de faire cela avec SED, AWK ou autre?

Merci


L'accès au savoir est la première liberté que chaque homme devrait avoir.

9 réponses

  1. pcsystemd Messages postés 734 Statut Membre 23
     

    Bon j'ai réussi a construire mes lignes avec AWK mais il reste encore le champ "vate" à renseigner.

    awk -F '|' '{print "update scard_vate set vate='\'''\'' where r_scard_ind=39 and r_scard_se_wb="$1";"}' awk -F '|' '{print "update scard_vate set vate='\'''\'' where r_scard_ind=37 and r_scard_se_wb="$1";"}' awk -F '|' '{print "update scard_vate set vate='\'''\'' where r_scard_ind=33 and r_scard_se_wb="$1";"}' awk -F '|' '{print "update scard_vate set vate='\'''\'' where r_scard_ind=35 and r_scard_se_wb="$1";"}'

    Pour rappel de la contrainte du champ "vate" :

    La valeur du champ "vate" doit aller du plus petit montant au plus grand comme l'exemple ci-dessous. On voit que la valeur de la ligne ayant le champ "r_scard_ind=39" est plus petit que la seconde ligne ayant le champ "r_scard_ind=37" qui elle même est plus petit que la troisieme ligne ayant le champ "r_scard_ind=33" et enfin la quatrieme ligne ayant le champ "r_scard_ind=35" doit avoir le montant dans le champ "vate" le plus élevé

    Merci
     


    0
  2. dubcek Messages postés 18627 Date d'inscription   Statut Contributeur Dernière intervention   5 660
     

    hello d'où viennent les nombres 6.7 + 10 + 20.52 + 62.78 ?

    0
  3. pcsystemd Messages postés 734 Statut Membre 23
     

    En fait les nombre viennent d'un fichier normalement mais la justement on a un fichier a 0 suite a un souci donc c'est a nous de choisir et de faire cela de façon automatique ces nombres mais en tenant compte des contraintes suivantes :

    - Que le total des 4 nombres = 100

    - Que la valeur du champ "vate" doit aller du plus petit montant au plus grand comme l'exemple ci-dessous. On voit que la valeur de la ligne ayant le champ "r_scard_ind=39" est plus petit que la seconde ligne ayant le champ "r_scard_ind=37" qui elle même est plus petit que la troisieme ligne ayant le champ "r_scard_ind=33" et enfin la quatrieme ligne ayant le champ "r_scard_ind=35" doit avoir le montant dans le champ "vate" le plus élevé

    Merci


    0
  4. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 944
     

    Bonjour,

    Personnellement, j'ai du mal à comprendre ce que tu veux faire, probablement parce que comme le souligne dubcek, on n'a pas toutes les données d'entrées. Peux-tu donner un jeu complet d'entrées et le résultat attendu ? Par ailleurs, le shell ne me semble pas le langage le plus pratique pour ton problème, es-tu ouvert à une solution écrite par exemple en python ?

    Bonne chance

    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. pcsystemd Messages postés 734 Statut Membre 23
     

    Bonjour,

    J'ai un peu avancé mais voici les informations.

    Données d'entrées

    - 1 fichier avec des ID qui sont les valeurs du champ "r_scard_se_wb" de mon AWK.

    6728111836
    6728155980
    6728509182
    6728140429
    6728316021
    6728388875
    6728344022
    6728463975

    - Mon script python qui génère mes 4 valeurs séparées par une virgule faisant un  total de 100  et qui les colle dans un fichier. Chacune des valeurs correspond au champ "vate" de mon AWK

    2.02,12.16,23.98,61.84
    3.73,13.71,15.16,67.40
    8.87,15.79,19.25,56.09
    9.84,11.07,17.73,61.36

    et enfin ma ligne AWK qui génère mes lignes SQL

    awk -F '|' '{print "update scard_vate set vate='\'''\'' where r_scard_ind=39 and r_scard_se_wb="$1";"}' 
    awk -F '|' '{print "update scard_vate set vate='\'''\'' where r_scard_ind=37 and r_scard_se_wb="$1";"}'
    awk -F '|' '{print "update scard_vate set vate='\'''\'' where r_scard_ind=33 and r_scard_se_wb="$1";"}' 
    awk -F '|' '{print "update scard_vate set vate='\'''\'' where r_scard_ind=35 and r_scard_se_wb="$1";"}'

    Mon besoin

    Pour chaque ID de mon premier fichier  et les 4 premiers nombres de mon second fichier (celui généré via python) il me faut  les 4 lignes  suivantes.

    ID :  6728111836

    Chiffres  : 2.02,12.16,23.98,61.84

    update scard_vate set vate='2.02' where r_scard_ind=39 and r_scard_se_wb=6728111836;
    update scard_vate set vate='12.16' where r_scard_ind=37 and r_scard_se_wb=6728111836;
    update scard_vate set vate='23.98' where r_scard_ind=33 and r_scard_se_wb=6728111836;
    update scard_vate set vate='61.84' where r_scard_ind=35 and r_scard_se_wb=6728111836;

    Il me reste a savoir comment matcher ces chiffres via mon AWK

    Merci


    0
  7. pcsystemd Messages postés 734 Statut Membre 23
     

    Je clôture car finalement j'ai trouvé la solution.

    Merci


    0
    1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 944
       

      Bonjour,

      Peux-tu prendre quelques instants pour expliquer ta solution (au cas où quelqu'un s'intéresse au même problème) ? Car il n'y a rien de plus triste qu'un forum avec des problèmes abordés sans la ou les réponse(s) correspondantes ;-)

      0
  8. pcsystemd Messages postés 734 Statut Membre 23
     

    Bonjour,

    C'est ce que je fais a chaque fois mais la je n'ai pas donné la solution car celle-ci est plus une bidouille qu'une solution mais cela a fait l'affaire pour moi donc.

    En gros j'ai fais un fichier par indicateur. donc un pour r_scard_ind=39, un autre pour  r_scard_ind=37 etc..

    Ensuite j'ai créée mes lignes AWK par indicateur puis j'ai regroupé toutes les lignes dans un seul fichier et je l'ai inséré en BDD.


    0
  9. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 944
     

    Bonjour,

    Je reviens sur ton message #5. Comme il y a déjà des bouts en python, je ne vois pas trop ce qui t'empêcherait de tout faire en python (ce serait plus simple).

    Si j'ai bien compris ton besoin, tu veux faire le produit cartésien de :

    • chaque vate, correspondant aux valeurs de chaque quadruplet issu du fichier généré par ton script python ;
    • chaque r_scard_se_wb, correspond à chaque ligne du fichier issu de ton script awk ;
    • chaque r_scard_int, correspond à des valeurs prédéfinies : [33, 35, 37, 39]

    Dans ce cas, voici comment on pourrait générer les requêtes SQL :

    from io import StringIO
    from itertools import product
    
    def make_sql_queries(f1, f2, r_scard_inds):
        queries = list()
        r_scard_se_wbs = [line1.strip() for line1 in f1.readlines()]
        for line2 in f2.readlines():
            vates = line2.strip().split(",")
            for (r_scard_se_wb, vate, r_scard_ind) in product(
                r_scard_se_wbs,
                vates,
                r_scard_inds
            ):
                queries.append(
                    f"update scard_vate set vate='{vate}' "
                    f"where r_scard_ind={r_scard_ind} "
                    f"and r_scard_se_wb={r_scard_se_wb};"
                )
        return queries
    
    # Fake file descriptors
    f1 = StringIO("""6728111836
    6728155980
    6728509182
    6728140429
    6728316021
    6728388875
    6728344022
    6728463975""")
    
    f2 = StringIO("""2.02,12.16,23.98,61.84
    3.73,13.71,15.16,67.40
    8.87,15.79,19.25,56.09
    9.84,11.07,17.73,61.36""")
    
    # Hardcoded 
    r_scard_inds = [33, 35, 37, 39]
    
    queries = make_sql_queries(f1, f2, r_scard_inds)
    print("\n".join(queries))

    Ici, j'utilise des StringIO car je pars du principe qu'à terme, tu liras les données d'entrées à partir de fichiers passés en paramètre à ce script.

    Résultat :

    update scard_vate set vate='2.02' where r_scard_ind=33 and r_scard_se_wb=6728111836;
    update scard_vate set vate='2.02' where r_scard_ind=35 and r_scard_se_wb=6728111836;
    update scard_vate set vate='2.02' where r_scard_ind=37 and r_scard_se_wb=6728111836;
    update scard_vate set vate='2.02' where r_scard_ind=39 and r_scard_se_wb=6728111836;
    update scard_vate set vate='12.16' where r_scard_ind=33 and r_scard_se_wb=6728111836;
    update scard_vate set vate='12.16' where r_scard_ind=35 and r_scard_se_wb=6728111836;
    update scard_vate set vate='12.16' where r_scard_ind=37 and r_scard_se_wb=6728111836;
    update scard_vate set vate='12.16' where r_scard_ind=39 and r_scard_se_wb=6728111836;
    update scard_vate set vate='23.98' where r_scard_ind=33 and r_scard_se_wb=6728111836;
    update scard_vate set vate='23.98' where r_scard_ind=35 and r_scard_se_wb=6728111836;
    update scard_vate set vate='23.98' where r_scard_ind=37 and r_scard_se_wb=6728111836;
    update scard_vate set vate='23.98' where r_scard_ind=39 and r_scard_se_wb=6728111836;
    update scard_vate set vate='61.84' where r_scard_ind=33 and r_scard_se_wb=6728111836;
    update scard_vate set vate='61.84' where r_scard_ind=35 and r_scard_se_wb=6728111836;
    update scard_vate set vate='61.84' where r_scard_ind=37 and r_scard_se_wb=6728111836;
    update scard_vate set vate='61.84' where r_scard_ind=39 and r_scard_se_wb=6728111836;
    update scard_vate set vate='2.02' where r_scard_ind=33 and r_scard_se_wb=6728155980;
    update scard_vate set vate='2.02' where r_scard_ind=35 and r_scard_se_wb=6728155980;
    ...

    Bonne chance

    0
  10. pcsystemd Messages postés 734 Statut Membre 23
     

    Merci mais ce n'est pas cela que je souhaite!

    Comme je l'indique précédemment le résultat des 4 indicateurs doit faire 100  et que la somme de chaque "r_scard_ind" aille en croissant sachant que "r_scard_ind=35" doit être le nombre le plus grand soit en croissant donc pour reprendre tes 4 premiers lignes il aurait fallu que l'on ai :

    update scard_vate set vate='6.02' where r_scard_ind=39 and r_scard_se_wb=6728111836;
    update scard_vate set vate='10.08' where r_scard_ind=37 and r_scard_se_wb=6728111836;
    update scard_vate set vate='22.02' where r_scard_ind=33 and r_scard_se_wb=6728111836;
    update scard_vate set vate='61.88' where r_scard_ind=35 and r_scard_se_wb=6728111836;

    0
    1. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 944
       

      Hello pcsystemd,

      J'ai un peu de mal à m'y retrouver. Pour mieux comprendre ce que tu veux, l'idéal serait que tu écrives ce que doit faire ton programme en pseudo code en indiquant clairement les paramètres d'entrées et je le traduis en python. Mais là, j'avoue que j'ai un peu de mal à réellement comprendre ce que tu veux faire et donc à t'aider.

      Bonne chance

      1