Ich möchte die Zeichenfolgen in der Spalte "Scorer" so aufteilen, dass der Name des Scorers beibehalten wird, nicht jedoch der Punktetyp (d. H. Der Text in den Klammern und die Klammern werden entfernt, um nur den Namen des Scorers in diesem Feld zu belassen).

Scorer
Ellis J.(Conversion Goal)
Ellis J.(Try)
Ellis J.(Conversion Goal)
Trueman J.(Try)
(Conversion Goal)Brough D.
(Try)McGillvary J.
(Try)McGillvary J.
(Penalty Goal)Brough D.
Ellis J.(Conversion Goal)

enter image description here

Es sollte wie folgt aussehen.

Scorer
Ellis J.
Ellis J.
Ellis J.
Trueman J.
Brough D.
McGillvary J.
McGillvary J.
Brough D.
Ellis J.
0
LouisD 20 Jän. 2019 im 15:19

5 Antworten

Beste Antwort

Die richtige Lösung wäre, die Datenbankstruktur zu korrigieren, indem der Tabelle eine weitere Spalte für den Bewertungstyp hinzugefügt wird. In der Tat sollten Sie wahrscheinlich eine Tabelle für Bewertungstypen haben und einen Fremdschlüssel aus dieser Tabelle hinzufügen.

Angenommen, Sie können die Datenbankstruktur nicht ändern, geschieht dies besser auf der Präsentationsebene. Jede Programmiersprache sollte es Ihnen ermöglichen, dies ganz einfach zu tun. Die Manipulation von Zeichenfolgen ist nicht die Stärke von SQL.

Davon abgesehen kann dies sicherlich mit reinem T-SQL erfolgen - mit einem einfachen allgemeinen Tabellenausdruck, um die Klammerindizes mit charindex abzurufen, und einem case-Ausdruck mit stuff in der select-Anweisung.

Erstellen und füllen Sie zunächst eine Beispieltabelle ( Bitte speichern Sie uns diesen Schritt in Ihren zukünftigen Fragen):

DECLARE @T AS TABLE
(
    Scorer nvarchar(100)
);

INSERT INTO @T (Scorer) VALUES
('Ellis J.(Conversion Goal)'),
('Ellis J.(Try)'),
('Ellis J.(Conversion Goal)'),
('Trueman J.(Try)'),
('(Conversion Goal)Brough D.'),
('(Try)McGillvary J.'),
('(Try)McGillvary J.'),
('(Penalty Goal)Brough D.'),
('Ellis J.(Conversion Goal)'),
-- Note: I've added some edge cases to the sample data:
('a row with (brackets) in the middle'),
('Just an open bracket (forgot to close '),
('Just a close bracket forgot to open)'),
('no brackets at all'),
('brackets ) in reversed order (');

Dann ist der CTE:

WITH CTE AS
(
    SELECT  Scorer, 
            CHARINDEX('(', Scorer) As OpenBrackets,
            CHARINDEX(')', Scorer) As CloseBrackets
    FROM @T
)

Die select-Anweisung:

SELECT  CASE WHEN OpenBrackets > 0 AND CloseBrackets > OpenBrackets
        THEN
           STUFF(Scorer, OpenBrackets, CloseBrackets - OpenBrackets + 1, '') 
        ELSE
            Scorer
        END As Scorer
FROM CTE

Ergebnisse:

Scorer
Ellis J.
Ellis J.
Ellis J.
Trueman J.
Brough D.
McGillvary J.
McGillvary J.
Brough D.
Ellis J.
a row with  in the middle
Just an open bracket (forgot to close 
Just a close bracket forgot to open)
no brackets at all
brackets ) in reversed order (
2
Zohar Peled 20 Jän. 2019 im 13:21

Die folgende Abfrage funktioniert für Sie

SELECT LTRIM(RTRIM(REPLACE(Scorer, SUBSTRING(Scorer, CHARINDEX('(', Scorer), CHARINDEX(')', Scorer) - CHARINDEX('(', Scorer) + 1), '')))
FROM <TABLENAME>
0
Venkatesh R 20 Jän. 2019 im 12:45

Diese beiden Informationen (Name und Aktion) sollten sich nicht in derselben Spalte befinden. Sie sollten eine separate Spalte für Name und Aktion erstellen. Und wenn die Position der Aktion (vor oder nach dem Namen) wichtig ist, benötigen Sie möglicherweise sogar eine zusätzliche Spalte dafür.

Wenn Sie Ihre Daten danach migriert haben - mit anderen Worten, wenn Sie bereinigt haben -, können Sie dennoch eine Ansicht oder eine berechnete Spalte erstellen, um das scorer so auszugeben, wie Sie es jetzt tun

ALTER TABLE my_table ADD scorer AS athlete_name + ' (' + action + ')'
0
Gert-Jan 20 Jän. 2019 im 12:51

Du könntest es versuchen:

SELECT Scorer
,CASE WHEN PATINDEX('%(%)%',Scorer) > 1 
THEN LEFT(Scorer, PATINDEX('%(%)%',Scorer)-1)
ELSE RIGHT (Scorer, LEN(Scorer) - CHARINDEX(')',Scorer,1) )
END AS ColumnName
FROM ScoreTable

Dies sollte funktionieren, vorausgesetzt, Sie erwarten nur 1 Instanz, wenn das Muster pro Zeile angezeigt wird, funktioniert jedoch unabhängig davon, ob sich die "()" - Daten vor oder hinter den Werten befinden

0
Gleb 20 Jän. 2019 im 12:52

Sie können diese Abfrage verwenden

with t(str) as
(
 select 'Ellis J.(Conversion Goal)' union all
 select '(Conversion Goal)Brough D.' union all   
 select '  (Try)McGillvary J.'   
)
select (case when charindex('(', ltrim(str)) = 1 then
              substring(str,charindex(')', str)+1,len(str))
             else           
               left(str, charindex('(', str) - 1)          
             end) as "Scorers"        
  from t

    Scorers
  --------------
   Ellis J.
   Brough D.
   McGillvary J.

Durch Beitrag von substring, charindex und left Funktionen zusammen. ltrim wird gegen die Wahrscheinlichkeit von Leerzeichen vor dem Zeichen ( am Anfang der Zeichenfolge verwendet.

Rextester-Demo

0
Barbaros Özhan 20 Jän. 2019 im 14:11