2
votes

SQL - Diviser la ligne de données et attribuer des valeurs de score

Je m'excuse pour le titre médiocre car je n'avais aucune idée de la meilleure façon de le formuler.

J'ai un tableau dans lequel je renvoie des lignes comme celle-ci:

Agent   | Policy Ref | Transaction Type | Score
Agent A | ABCD01EF01 | New Business     | 0.5 
Agent B | ABCD01EF01 | New Business     | 0.5
Agent C | ZYXA01EF01 | New Business     | 1.0
Créer un code
    CREATE TABLE #temptable ( [Opener] varchar(50), [Closer] varchar(50), [PolicyRef] varchar(10), [Transaction Type] varchar(14) )
INSERT INTO #temptable
VALUES
( 'Agent C', 'Agent C', 'ZYXA01EF01', 'New Business' ), 
( 'Agent A', 'Agent B', 'ABCD01EF01', 'New Business' )

DROP TABLE #temptable

Nous obtenons essentiellement un score de 1,0 pour le moment, pour chaque ligne si l'Opener = Closer puis le 'Score' La colonne doit être 1.0 et ne renvoyer qu'une seule ligne, cependant si l'Opener Closer qu'il devrait y avoir 2 lignes avec le 'Score' étant 0,5 divisé entre l'Opener et Closer, la sortie doit être comme ceci

Opener  | Closer  | Policy Ref | Transaction Type
Agent A | Agent B | ABCD01EF01 | New Business
Agent C | Agent C | ZYXA01EF01 | New Business

Je pensais à une application croisée avec row_numbering pour définir s'il y avait plus d'une ligne par "Ref Policy" mais je ne semble pas être en mesure de le faire fonctionner.

J'ai fait cela auparavant mais c'était une procédure stockée utilisant des tables temporaires et des cte pour mettre à jour et déplacer les informations, je recherche une version "faible en gras" si vous voulez.


0 commentaires

3 Réponses :


1
votes

Utilisez apply avec les expressions case :

select v.agent, t.policy_ref, t.transaction_type,
       (case when t.opener = t.closer then 1.0 else 0.5 end) as score
from #temptable t cross apply
     (values (t.opener, 1),
             (t.closer, 2)
     ) v(agent, which)
where (t.opener <> t.closer) or (which = 1)

Ou:

select v.agent, t.policy_ref, t.transaction_type, v.score
from #temptable t cross apply
     (values (opener, (case when t.opener = t.closer then 1.0 else 0.5 end)),
             (case when t.opener <> t.closer then t.closer end, 0.5)
     ) v(agent, score)
where v.agent is not null;

p>


1 commentaires

Gordon J'aspire à pouvoir écrire des solutions aussi rapidement :) Merci beaucoup monsieur. Je savais que j'étais dans la bonne direction avec une application croisée ne savais tout simplement pas comment obtenir le bon résultat.



2
votes

Une autre option est un UNION ALL

Exemple

Select *
      ,Score = 1.0  / sum(1) over(partition by PolicyRef) 
 From  (
        Select Agent = Opener
             ,PolicyRef
             ,[Transaction Type]
         from #temptable
        Union All
        Select Agent = Closer
             ,PolicyRef
             ,[Transaction Type]
         from #temptable
         Where Opener<>Closer
       ) A

Retours strong >

 entrez la description de l'image ici


0 commentaires

0
votes

Il me semble que vous essayez de créer un tableau trop complexe, pour des données qui seraient mieux organisées en plusieurs tableaux. Cela devrait vous aider à résoudre votre problème de comptage.

Il serait logique pour moi de créer plusieurs tables afin que vous puissiez attribuer des clés uniques. Je créerais une table de stratégie avec une clé unique pour chaque référence de stratégie Puis une autre table pour chaque agent avec une clé unique par agent. Et puis une troisième table qui serait similaire à la table que vous avez créée.

Agent   | Policy Ref | Transaction Type | Score
Agent A | ABCD01EF01 | New Business     | 0.5 
Agent B | ABCD01EF01 | New Business     | 0.5
Agent C | ZYXA01EF01 | New Business     | 1.0

Ensuite, à travers des requêtes avec des jointures et des champs calculés, vous pouvez créer votre table de score.

XXX

Ensuite, vous pouvez utiliser un nombre d'agents pour chaque référence de stratégie.

Vous pouvez avoir d'autres moyens plus simples ou élégants de le faire, mais au moins je pense que cela devrait travail.


0 commentaires