3 Stimmen

SQL Server-Abfrage - Frage zur Schleife

Ich versuche, eine Abfrage zu erstellen, die eine Kreuztabelle mit etwa 40 benutzerdefinierten Spalten erzeugt, die J oder N anzeigen.

SELECT DISTINCT [Company],
       [Option1],
       [Option2],
       [Option3],              
       CASE
         WHEN [Table1].[ID1] IN (SELECT ID2 FROM Table2 WHERE Variable = 1 AND Bit = 1) THEN 
           'Y'
         ELSE 'N'
       END AS 'CustomColumn1:',
       CASE 
         WHEN [Table1].[ID1] IN (SELECT ID2 FROM Table2 WHERE Variable = 2 AND Bit = 1) THEN 
           'Y'
         ELSE 'N'
       END AS 'CustomColumn1:',      
       CASE 
         WHEN [Table1].[ID1] IN (SELECT ID2 FROM Table2 WHERE Variable = 3 AND Bit = 1) THEN 
           'Y'
         ELSE 'N'
    END AS 'CustomColumn1:',
    .............
    -- REPEAT ANOTHER 40 times
    FROM [Table1] 
    WHERE [Table1].[OtherCondition] = 'True'
    ORDER BY [Company]

Also meine Frage ist, wie ich eine Schleife (while? for?) erstellen, die Schleife auf Variable und Y oder N der Zeile auf der Grundlage der Bedingung zuweisen wird, anstatt 40+ Case-Anweisungen zu erstellen?

2voto

Ryan Tenney Punkte 1805

Sie könnten keine Schleife verwenden, aber Sie könnten eine gespeicherte Prozedur/Funktion erstellen, um die Unterauswahl und den Fallausdruck durchzuführen, und diese 40 Mal aufrufen.

Sie könnten auch die Leistung der Unterauswahl verbessern, indem Sie sie in

SELECT 1 FROM Table2 WHERE EXISTS [Table2].[ID2] = [Table1.ID1] AND Variable = 3 AND Bit = 1

2voto

GSerg Punkte 73326

Eine Schleife (d. h. die Iteration durch einen Cursor) arbeitet mit Zeilen, nicht mit Spalten. Sie müssen immer noch 40 Ausdrücke haben, einen für jede Spalte, und die Leistung wird schrecklich sein.

Lassen Sie SQL Server seine Arbeit machen. Und leisten Sie Ihren Beitrag, indem Sie genau sagen, was Sie brauchen, und geeignete Indizes erstellen. Das heißt, ersetzen Sie

CASE WHEN [Table1].[ID1] IN (SELECT ID2 FROM Table2 WHERE Variable = 2 AND Bit = 1)

mit

CASE WHEN EXISTS (SELECT 0 FROM Table2 WHERE ID2 = [Table1].[ID1] AND Variable = 2 AND Bit = 1)

1voto

Thomas Punkte 62314

Wenn die Ausgabe so stark vom Schema abweicht, stellt sich die Frage, ob das Schema die Geschäftsanforderungen richtig modelliert. Daher würde ich empfehlen, nur das SQL zu schreiben. Sie können die SQL folgendermaßen vereinfachen:

Select Company
    , Option1, Option2, Option3
    , Case When T2.Variable = 1 Then 'Y' Else 'N' End As CustomCol1
    , Case When T2.Variable = 2 Then 'Y' Else 'N' End As CustomCol2
    , Case When T2.Variable = 3 Then 'Y' Else 'N' End As CustomCol3
    , Case When T2.Variable = 4 Then 'Y' Else 'N' End As CustomCol4
... 
From Table1 As T1
        Left Join Table2 As T2
            On T2.ID2 = T1.ID
                And T2.Bit = 1
Where T1.OtherCondition = 'True'
Group By T1.Company
Order By T1.Company

Wenn Sie etwas schreiben möchten, das Ihnen hilft, diese Case-Anweisungen automatisch zu generieren (und Sie SQL Server 2005+ verwenden), könnten Sie etwas wie folgt tun:

With Numbers As
    (
    Select 0 As Value
    Union All
    Select Value + 1
    From Numbers
    Where Value < 41
    )
Select ', Case When T2.Variable = ' + Cast(N.Value As varchar(10)) + ' Then ''Y'' Else ''N'' End As CustomCol' + Cast(N.Value As varchar(10))
From Numbers As N

Sie führen die Abfrage aus, kopieren die Ergebnisse und fügen sie in Ihre Prozedur oder Ihren Code ein.

0voto

Nitin Midha Punkte 2258

Eine Möglichkeit wäre die Verwendung der Pivot-Anweisung, die in MS SQL 2005+ enthalten ist. Aber selbst da müssen Sie 1 ... 40 fest kodierte Spalten in die Pivot-Anweisung einfügen.

Andere Weise, die ich denken kann, ist dynamisches SQL zu erstellen, aber es ist nicht so sehr empfohlen, Also, was wir tun können, ist wir können eine dynamische SQL-Abfrage erstellen, indem Sie eine while-Schleife auf Tabelle und kann die große Sql erstellen und dann können wir es ausführen, indem Sie sp_execute. Die Schritte wären also.

int @loopVar

SET @loopVar = 0

int @rowCount

varchar @SQL 

SET @SQl = ''
Select @rowcount = Count(ID2) from Table2

WHILE(@loopVar <= @rowCount)

BEGIN

// create ur SQL here

END

sp_execute(@SQL)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X