2009-06-05 11 views
11

Ich kann mit LINQ so etwas schreiben:Kann ich eine in-Zyklus Variable in T-SQL SELECT (wie LET in LINQ) definieren?

var selection = from person in personList 
       let initials = person.FirstName[0] + person.LastName[0] 
       select initials; 

Kann ich etwas ähnliches mit SQL, wie vielleicht:

SELECT @Initials 
FROM [Person] 
SET @Initials = SUBSTRING (Person.FirstName, 1, 1) + SUBSTRING (Person.LastName, 1, 1) 

Wahrscheinlich nicht, aber vielleicht gibt es einen Trick?

Ich brauche eine vorberechnete Variable für die weitere Verwendung in einer komplexen WHERE-Klausel, um extreme Komplexität und Codewiederholung zu vermeiden.

+2

Verwenden Sie nicht 't-sql' für ein Tag - verwenden Sie stattdessen 'tsql'. Bitte beachten Sie die Vorschläge, wenn Sie Ihre Frage markieren - ein Tag mit einer Zahl <10 nach dem Namen sollte wahrscheinlich vermieden werden. –

+0

Warum? In der Regel wird "T-SQL" verwendet, nicht jedoch TSQL. – User

+0

@Mastermind, leider haben mehr Leute historisch tsql verwendet, und wir haben es aus Gründen der Konsistenz neu markiert. –

Antwort

12

Eine saubere Methode, dies ohne Hinzufügen einer temporären Tabelle, Schleifen usw. zu tun, wäre mit einem Common Table Expression (CTE). Beispiel:

;WITH PersonsWithInitials AS 
(
    SELECT 
     SUBSTRING (COALESCE(Person.FirstName,''), 1, 1) 
     + SUBSTRING (COALESCE(Person.LastName,''), 1, 1) AS Initials,    
     FirstName, 
     LastName, 
     City 
    FROM 
     [Person] 
) 
SELECT 
    FirstName, 
    LastName, 
    City, 
    Initials 
FROM 
    PersonsWithInitials 
WHERE 
    /* Complex WHERE clause goes here and it can reference Initials as if it were a field */ 

Anstelle des leeren ‚‘ oben, können Sie einen Zeitraum oder etwas anderes null Namensfelder stehen in für verwenden könnten.

Dies sollte alles in einem einzigen SQL-Aufruf von .NET ausgeführt werden - der CTE ist nicht in der Datenbank wie eine Ansicht, gespeicherte Prozedur, temporäre Tabelle usw.

+0

müsste für NULL-Fälle – van

+2

testen das OP sagt "Ich muss eine vorberechnete Variable für die weitere Verwendung in einer komplexen WHERE-Klausel haben". Aus ihrer Frage sieht es so aus, als ob sie die Ergebnisse in einer Variablen speichern und nicht nur eine einmalige Ergebnismenge zurückgeben wollen. Wenn nicht, dann ist dies eine gute Antwort, sonst müssen sie meine Antwort überprüfen ... –

+2

-1 das ist nicht was der OP fragt, wenn ich ihn verstehe. – JoshBerke

2
SELECT Initials 
    = SUBSTRING (Person.FirstName, 1, 1) 
     + SUBSTRING (Person.LastName, 1, 1) 
FROM [Person] 

oder

gespeichert
SELECT SUBSTRING (Person.FirstName, 1, 1) 
     + SUBSTRING (Person.LastName, 1, 1) 
      AS Initials 
FROM [Person] 

Wenn Sie es später verwenden, ist ein klar lesbarer Weise eine gemeinsame Tabelle exprssion zu verwenden (die anstelle von verschachtelten gestapelt werden können):

WITH Person2 AS (
    SELECT SUBSTRING (Person.FirstName, 1, 1) 
      + SUBSTRING (Person.LastName, 1, 1) 
       AS Initials 
    FROM [Person] 
) 
SELECT Initials, COUNT(*) AS Record_Count 
FROM Person2 
GROUP BY Initials 
3

Sieht aus, als ob Sie nur versuchen, die Initialen für später in eine Variable zu bringen. Versuchen Sie es auf diese Weise ...

DECLARE @Initials varchar(2) 

SELECT @Initials = SUBSTRING (Person.FirstName, 1, 1) + SUBSTRING (Person.LastName, 1, 1) 
FROM [Person] 
WHERE .... 

Wenn Sie versuchen, dass als ein Satz zu verwenden und nicht einen einzigen Wert, sollten Sie suchen eine Unterabfrage oder CTE mit der anderen komplexen Abfrage zu tun.

-1

wenn Sie eine Reihe von Initialen behalten wollen mehrmals zu verwenden, oder als Teil einer größeren Abfrage, wie folgt vorgehen:

declare @TableVariable table (Initials varchar(200) 

INSERT INTO @TableVariable 
     (Initials) 
    SELECT 
     ISNULL(SUBSTRING(Person.FirstName,1,1),'')+ISNULL(SUBSTRING(Person.LastName,1,1),'') 
    FROM Person 

SELECT * FROM @TableVariable 

SELECT * FROM @TableVariable 

wenn Sie viele Zeilen tun #temp Tabellen schneller sind. Außerdem wäre es wahrscheinlich schneller, eine abgeleitete Tabelle in einer größeren Abfrage als eine temporäre Tabelle zu erstellen.

+0

Eine Tabellenvariable kann die Leistung drastisch beeinträchtigen, wenn die Abfrage des OP nach mehr als nur Initialen gefiltert wird. In den meisten Fällen ist ein CTE besser, da er die Indizes der zugrunde liegenden Tabelle verwendet (eine Tabellenvariable nicht). – richardtallent

+0

@richhardtallent, lesen Sie die Frage & meine Antwort! Ich sagte "wenn Sie eine Reihe von Initialen mehrere Male verwenden möchten". Auch aus der Frage des OP versucht er, die Ergebnisse in eine Variable zu bringen. Mit einem CTE ist das nicht möglich. Ich schlug nur eine andere Art von Lösung vor! –

Verwandte Themen