2010-09-02 4 views
1

SQL Server je la requête SQL suivante:Aide avec le formatage de chaîne dans Query

SELECT DISTINCT ProductNumber, PageNumber FROM table

Je suis en train de modifier la requête afin que PageNumber sera formaté. Vous voyez, PageNumber est dans l'un des formats suivants, où 'x' est un chiffre:

  • xxx, xxx
  • xxx
  • xxx-xxx
  • xx, xxx-xxx
  • xx-xx, xxx
  • xx-xx, xxx-xxx

Je veux formater PageNumber de sorte qu'il est seulement dans le format suivant: xxx. Pour ce faire, j'analyser les numéros suivants bolded des formats ci-dessus:

  • xxx, xxx
  • xxx
  • xxx -xxx
  • xx, xxx -xxx
  • xx-xx, xxx
  • xx -XX, xxx-xxx

Je veux faire tout cela sans écrire de fonctions, mais je ne sais pas si cela est possible. Je ne parviens pas à « détecter » tous les différents formats, cependant:

Voici ce que j'ai jusqu'à présent:

SELECT ProductNumber, 
     CASE WHEN CHARINDEX(',', PageNumber) > 0 
      THEN SUBSTRING(PageNumber, 0, CHARINDEX('-', PageNumber)) 
      WHEN CHARINDEX('-', PageNumber) > 0 
      THEN SUBSTRING(PageNumber, 0, CHARINDEX('-', PageNumber)) 
      ELSE PageNumber 
     END AS PageNumber 
FROM table 
WHERE PageNumber IS NOT NULL 
    AND PageNumber <> '' 

Quelqu'un peut-il me proposer une aide? Merci!

Répondre

3

Mode d'utilisation correspondant plutôt que CHARINDEX

CASE oblige également la commande d'évaluation qui aide ici pour le 3e cas qui chevauche les 2 premiers cas.

Non testé, quelque chose comme

CASE 
    WHEN PageNumber LIKE '[0-9][0-9][0-9]%' THEN LEFT(PageNumber, 3) 
    WHEN PageNumber LIKE '[0-9][0-9]-[0-9][0-9], [0-9][0-9][0-9]') THEN RIGHT(PageNumber , 3) 
    WHEN PageNumber LIKE '[0-9][0-9]%') THEN LEFT(PageNumber, 2) 
END 
+0

Excellente réponse, +1 – ajdams

+0

ne fonctionne pas, la syntaxe échoue: syntaxe incorrecte près ')'. Et si les données sont 'xxxx' ou' xxxx-xxxx', vous n'obtiendrez que les trois premiers chiffres. –

+0

@KM, il suffit de supprimer les parenthèses avant le THEN dans la seconde QUAND. –

2

essayez ceci:

DECLARE @YourTable table (ProductNumber int, PageNumber varchar(20)) 
INSERT @YourTable VALUES (1,'123, 456') 
INSERT @YourTable VALUES (2,'123') 
INSERT @YourTable VALUES (3,'123-456') 
INSERT @YourTable VALUES (4,'12, 345-678') 
INSERT @YourTable VALUES (5,'12-34, 567') 
INSERT @YourTable VALUES (6,'12-34, 567-789') 

;WITH AllNumbers AS ---builds a Numbers table 1-100 
( SELECT 1 AS Number 
    UNION ALL 
    SELECT Number+1 
     FROM AllNumbers 
     WHERE Number<101 
) 
, RowChars AS --one row for each non-numeric single character value per @YourTable row 
( SELECT DISTINCT 
     ProductNumber,Number, SUBSTRING(PageNumber,Number,1) AS CharacterOF 
     FROM @YourTable 
      INNER JOIN AllNumbers ON 1=1 
     WHERE SUBSTRING(PageNumber,Number,1) IS NOT NULL AND SUBSTRING(PageNumber,Number,1) NOT LIKE '[0-9]' AND SUBSTRING(PageNumber,Number,1)!='' 
) 
,FirstSplit AS --get first non-numeric single character value per @YourTable row 
( SELECT 
     ProductNumber,MIN(Number) AS SplitOf 
     FROM RowChars 
     GROUP BY ProductNumber 
) 
SELECT 
    t.ProductNumber, LEFT(t.PageNumber,COALESCE(s.SplitOf-1,LEN(t.PageNumber))) AS NewPage,t.PageNumber AS OldPage 
    FROM @YourTable     t 
     LEFT OUTER JOIN FirstSplit s ON t.ProductNumber=s.ProductNumber 

SORTIE:

ProductNumber NewPage    OldPage 
------------- -------------------- -------------------- 
1    123     123, 456 
2    123     123 
3    123     123-456 
4    12     12, 345-678 
5    12     12-34, 567 
6    12     12-34, 567-789 

(6 row(s) affected) 
+0

Merci d'avoir pris le temps de le faire. Bien que la correspondance de motifs soit suffisante pour moi, j'économise votre solution pour la regarder plus en profondeur car il semble que je puisse en faire plus. Merci! – littleK