-1
votes

Comment copier une ligne et diviser l'une des colonnes en fonction de certains critères de Oracle SQL?

J'ai une table d'une valeur de 250 000 données et de ces données, je dispose de 1000 lignes qui ont les mêmes données dans chaque barre de référence une colonne de référence différente. Ce qui suit est un exemple: xxx pré>

Maintenant ce que je voudrais faire est pour chaque ligne où la référence a un numéro à 8 chiffres puis un espace puis un nombre à 13 chiffres, je voudrais Copiez cette ligne mais scinder le ref_no afin que j'ai une ligne avec le ref_no à 8 chiffres et 1 avec le 13 chiffres. P>

Dans l'exemple ci-dessus, le code ne doit fonctionner qu'avec la première ligne, car Graeme ne répond pas à ce critère car Réf_no dispose de 2 chiffres, puis un espace doit donc échouer immédiatement. Pour Sarah, le code échouera car le REF_NO pour la 2e partie n'a que 12 chiffres que 13. Pour Graeme et Sarah, leurs données resteront toujours dans les rangées simples avec le ref_no qu'ils ont. P>

Je suppose que je devine. Cela doit être fait avec des expressions régulières pour trouver un modèle assorti, malheureusement, je n'ai pas encore tenté de code comme à nouveau que son nouveau pour moi et la copie de la ligne m'a jeté légèrement comme ça n'a pas fait quelque chose comme ça avant d'être donc aimerait quelques conseils sur les meilleures pratiques pour déplacer cela en avant. P>

BTW Voici comment il devrait ressembler à la table (j'ai une colonne d'identité automatique afin que les nouvelles lignes auront de nouveaux identifiants assignés ainsi ): p> xxx pré>

merci d'avance. p>

EDIT 04/02/2020 --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------- P>

excuses pour le retard, malheureusement pas trop bien. Merci gars pour toutes vos réponses. Yunnosch, Wiktor, Rob telle que vous avez demandé ce qui suit est ma table de création et insérer des relevés et exactement ce que je cherche juste pour le rendre beaucoup plus clair sur ce que je demande. Les excuses auraient dû être incluses au début. P>

Create Table: P>

ID | Name   | Tel_No     | Post_Code | Ref_No
2 | Graeme | 7900789012 | ME1 2DE   | 12 345 5678901234567
3 | Sarah  | 7900456789 | ME1 2FG   | 90123456 890123456789
4 | Damian | 7900123456 | ME1 2BC   | 12345678
5 | Damian | 7900123456 | ME1 2BC   | 1234567891234


11 commentaires

meta.stackoverflow.com/questions/333952/... (envisagez d'utiliser une base de données de jouets SQLite fournir une commande utilisable de la commande).


Deux rangées pour les deux parties de la ref_no ou deux colonnes? Ce dernier semble plus probable dans la situation que vous décrivez. Pensez à répondre en montrant le résultat que vous imaginez. Faites-le en taper en taper manuellement.


Votre description sonne comme le résultat souhaité est Damian | 7900123456 | ME1 2BC | 12345678 et Damian | 7900123456 | ME1 2BC | 1234567891234 . Mais je pense que vous pourriez signifier Damian | 7900123456 | ME1 2BC | 12345678 | 1234567891234 .


Où voulez-vous le résultat? En tant que lignes supplémentaires (paires de lignes) dans la table existante? Je pense que cela briserait la sémantique de la colonne REF_NO. Peut-être que de nouvelles lignes (paires de lignes) dans une table séparée? Cela permettrait de remplacer la colonne unique Réf_no par deux colonnes REF_NO8 et REF_NO13.


Salut Yunnosch, merci pour votre réponse. Je voudrais 2 rangées séparées, il suffit d'éditer mon poste pour montrer quelle réponse finale devrait ressembler. Merci beaucoup BTW.


Assurez-vous d'indiquer les lignes d'origine, restent-ils? Sont-ils supprimés? Surtout ces lignes ignorées par le traitement. Veuillez également expliquer ce que vous entendez par "échec". Si le traitement s'arrête? Ou tout simplement pas traiter ces lignes?


La table d'origine restera telle qu'elle est, je créerai une table de mise en scène pour déplacer cette partie du processus afin de ne pas perdre le jeu de données d'origine. En termes d'échec, lorsque le code ne répond pas aux critères, il se déplace simplement sur la ligne suivante et ainsi de suite jusqu'à ce que aucune ligne de lignes ne soit disponible.


Veuillez faire un exemple de reproductible minimal en affichant quelques lignes de Créer une table ... et insérer ... , qui fait une base de données de jouets sur mesure.


ok va faire, merci


La valeur dans Réf_no garantit-elle des chiffres et des blancs? C'est à dire. Est-ce fiable libre de par exemple. Lettres, caractères spéciaux, etc.?


Combien de choses pouvez-vous faire vous-même? Pouvez-vous par exemple Au moins créer une nouvelle table et remplissez-la avec toutes les lignes? S'il vous plaît afficher le code pour cela. Si cela est déjà au-delà de vous, alors je suis désolé de dire que vous ne posez pas une question sur un problème de programmation, mais demander à quelqu'un de faire la programmation pour vous. Dans ce cas, je recommande d'abord suivre quelques tutoriels. De plus, comme par exemple visible dans la réponse ci-dessous, la fourniture d'une base de données de jouets est très importante pour permettre aux intervenants de tester leur code et d'éviter de plus facilement les détails manquants de ce que vous voulez réaliser.


3 Réponses :


0
votes

Cette méthode comment vous pouvez diviser, je vais ajouter un code complet:
Ceci est pour le premier chiffre de 8 chiffres:

with 
tb_split8 as (
select Name, substr(ref_no,0,8) as split8 from stack where instr(ref_no,' ') >= 9),
tb_split13 as( 
select Name, substr(ref_no,10,13) as split13 from stack where instr(ref_no,' ',10) = 0 and length(substr(ref_no,10,13)) = 13)
select a.Name, Post_code, Tel_no, split8, split13 from stack a join tb_split8 b on a.Name = b.Name join tb_split13 c on b.Name = c.Name ;


4 commentaires

Cela n'a pas attendu l'exigence à 13 chiffres.


Il copiera également 8 caractères non vierges contenant des lettres. C'est à dire. Cela suppose qu'il n'y a que des chiffres. (Je pense aussi que le chiffre n'est garanti que garantit, mais OP n'a pas confirmé.)


@Yunnosch s'il vous plaît essayez à nouveau j'ai corrigé une ficelle.


Essayer est difficile depuis que ni OP ni vous n'avez fourni une base de données de jouets. Mais je suis à peu près sûr que votre résultat n'a qu'une ligne où OP veut deux.



0
votes

Même sans expressions régulières, vous pouvez obtenir deux lignes selon les critères que vous avez comme suit

with data
  as (
        select '12345678 1234567890123' as x /*This matches the 8<SPACE>13*/
         from dual
        union all
        select '1234567 1234567890123' as x
         from dual
     ) 
   ,criteria_data
    as (
        select t.*
               ,substr(x,1,instr(x,' ')) as first_part
               ,substr(x,instr(x,' ')+1,length(x)) as second_part
          from data t
         where length(x)-length(replace(x,' ',''))=1  /*Check for exactly one space*/
           and length(substr(x,1,instr(x,' ')))=8 /*check for first segment with 8 char*/
           and length(substr(x,instr(x,' ')+1,length(x)))=13 /*Check for second segment with 13 char length*/
       )
select a.*,case when lvl=1 then first_part when lvl=2 then second_part end as ref_no 
  from criteria_data a
  join (select level as lvl 
          from dual 
        connect by level<=2) b
    on 1=1


0 commentaires

0
votes

Vous pouvez utiliser REGEXP_SUBSTR () et SUBSTR () Fonctionne ensemble pour une comparaison mutuelle si les parties scindées sont égales. Puis générer une autre ligne pour chaque ligne satisfaisant le condition: xxx

ou utilisez directement regexp_ike () (avec substr () ) fonctionne dans le condition: xxx

Démo


0 commentaires