2016-07-12 14 views
0

Ich habe die folgende Tabellenstruktur:SQL Server: Reuse berechnete Variable in select-Klausel

col1  col2  col3 col4 
------------------------------- 
aK  Mbcd  ABc defgh 

col2, col3 und col4 Spalten sind vom Typ varchar(100) und col1 hat varchar(500) geben.

Ich brauche eine Auswahlabfrage die Ausgabe wie folgt

col1 col2  col3 col4 
------------------------------- 
aK,Mb cd,A  Bc,d efgh 

Logic, wie unten erwähnt erklärt haben: maximal 4 Zeichen Im Ergebnis Col2, col3 und col4

  1. haben aber col1 kann mehr als 4 Zeichen bis zu 100 haben.

  2. Wenn eine Spalte mehr Zeichen hat, werden die letzten 4 Zeichen in derselben Spalte und anderen beibehalten Zusätzliche Spalten werden mit dem Wert der vorherigen Spalte verknüpft, getrennt durch Komma ,, und dieselbe Regel wird auch auf die verketteten Werte angewendet.

Ich habe die folgende T-SQL-Anweisung geschrieben. Es funktioniert gut für die letzten zwei Spalten. Aber ich will neue berechnete Wert col3 verwenden, zusätzliche Zeichen abzustreifen, nachdem einige von col4 Zugabe

SELECT 
    CASE 
     WHEN X.Col4Length > 4 
      THEN concat(X.col3, ',', substring(x.col4, 0, X.Col4Length - 3)) 
      ELSE X.col3 
    END AS col3, 
    CASE 
     WHEN X.Col4Length > 4 
      THEN substring(x.col4, X.Col4Length - 3, x.Col4Length) 
      ELSE X.col4 
    END AS col4 
FROM 
    (SELECT 
     Col1, Col2, Col3, Col4, 
     Len(Col1) AS Col1Length, 
     Len(Col2) AS Col2Length, 
     Len(Col3) AS Col3Length, 
     Len(Col4) AS Col4Length 
    FROM  
     mytable) X 
+0

Es scheint, als ob Sie SQL hier missbrauchen - fühlt sich mehr an Wie ein Präsentationsthema, das an einer Datenquelle liegt, und daher wahrscheinlich besser in einem Anwendungs-/Berichtswerkzeug behandelt wird als in SQL. Offensichtlicher Randfall - was ist, wenn die Gesamtmenge an Text die von Ihnen angegebenen Kapazitäten überschreitet? Z.B. Eingabegrößen sind '(100,100,100,100)' und Ausgabegrößen sind '(100,4,4,4)'. –

+0

Ok danke für das Aufzeigen eines anderen Problems. Ich werde col1 Größe auf '500' setzen –

Antwort

0

Sie wollen Wiederverwendung berechneten Größen

Es gibt zwei Set-basierte/Inline/adhoc Ansätze (und viele mehr hässlich Verfahren):

  • CTE s dies für den ganzen Satz im Voraus zu tun
  • CROSS APPLY für das gleiche auf Zeilenebene

Probieren Sie es wie dieser (CTE Ansatz)

DECLARE @tbl TABLE(col1 VARCHAR(100),col2 VARCHAR(100),col3 VARCHAR(100),col4 VARCHAR(100)); 
INSERT INTO @tbl VALUES 
('aK','Mbcd','ABc','defgh') 
,('123456','abc','3456','123456789'); 

WITH ResolveCol4 AS 
(
    SELECT * 
      ,RIGHT(col4,4) AS Col4_resolved 
      ,col3 + ',' + CASE WHEN LEN(col4)>4 THEN SUBSTRING(col4,1,LEN(col4)-4) ELSE '' END AS col3_New 
    FROM @tbl 
) 
,ResolveCol3 AS 
(
    SELECT * 
      ,RIGHT(col3_New,4) AS Col3_resolved 
      ,col2 + ',' + CASE WHEN LEN(col3_New)>4 THEN SUBSTRING(col3_New,1,LEN(col3_New)-4) ELSE '' END AS col2_New 
    FROM ResolveCol4 
) 
,ResolveCol2 AS 
(
    SELECT * 
      ,RIGHT(col2_New,4) AS Col2_resolved 
      ,col1 + ',' + CASE WHEN LEN(col2_New)>4 THEN SUBSTRING(col2_New,1,LEN(col2_New)-4) ELSE '' END AS col1_New 
    FROM ResolveCol3 
) 
SELECT col1_new,Col2_resolved,Col3_resolved,Col4_resolved 
FROM ResolveCol2 

Das Ergebnis

aK,Mb   cd,A Bc,d efgh 
123456,abc,34 56,1 2345 6789 
2

Mein Versuch mit einer einfachen Unterabfrage

with t1 as (
select 'aK' col1, 'Mbcd' col2, 'ABc' col3, 'defgh' col4 
--- 
SELECT LEFT(col, LEN(col) - 12) col1, 
     RIGHT(LEFT(col, LEN(col) - 8), 4) col2, 
     RIGHT(LEFT(col, LEN(col) - 4), 4) col3, 
     RIGHT(col, 4) AS col4 
FROM 
(
    SELECT col1+','+col2+','+col3+','+col4 AS col 
    FROM t1 
) t; 
+0

Das ist viel einfacher als meins ... +1 von meiner Seite! – Shnugo