2009-06-05 6 views
11

Je peux écrire quelque chose comme ça avec LINQ:Puis-je définir une variable dans le cycle dans T-SQL SELECT (comme LET dans LINQ)?

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

Puis-je faire quelque chose de similaire avec SQL, comme peut-être:

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

Probablement pas, mais peut-être il y a un truc?

Je dois avoir une variable précalculée pour une utilisation ultérieure dans une clause WHERE complexe afin d'éviter une extrême complexité et la répétition du code.

+2

N'utilisez pas 't-sql' pour une balise - utilisez plutôt 'tsql'. S'il vous plaît faites attention aux suggestions de suggestions lors du marquage de votre question - toute étiquette avec un nombre <10 après le nom devrait probablement être évitée. –

+0

Pourquoi? "T-SQL" est généralement utilisé mais pas TSQL. – User

+0

@Mastermind, malheureusement, plus de gens utilisaient tsql par le passé, et nous avons donc ré-étiqueté cela par souci de cohérence. –

Répondre

12

Une manière propre de le faire sans ajouter une table temporaire, une boucle, etc. serait avec une expression de table commune (CTE). Exemple:

;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 */ 

Au lieu de vide « » ci-dessus, vous pouvez utiliser une période ou quelque chose d'autre à se substituer aux champs de nom null.

Tout cela devrait être exécuté en un seul appel SQL de .NET - le CTE est pas enregistré dans la base de données comme une vue, une procédure stockée, table temporaire, etc.

+0

aurait besoin de tester pour les cas NULL – van

+2

l'OP dit "J'ai besoin d'avoir une variable précalculée pour une utilisation ultérieure dans une clause complexe de WHERE". à partir de leur question, il semble qu'ils veulent stocker les résultats dans une variable, et pas seulement retourner un ensemble de résultats unique. Si non, alors c'est une bonne réponse, sinon ils doivent vérifier ma réponse ... –

+2

-1 ce n'est pas ce que l'op me demande si je le comprends. – JoshBerke

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

ou

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

Si vous devez l'utiliser plus tard, d'une manière clairement lisible est d'utiliser un exprssion de table commune (qui peut être empilé, au lieu de imbriquée):

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

On dirait que vous essayez simplement d'obtenir les initiales dans une variable pour plus tard. Essayez cette façon ...

DECLARE @Initials varchar(2) 

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

Si vous essayez de l'utiliser comme un ensemble et non une seule valeur, vous devriez regarder faire une sous-requête ou CTE avec votre autre requête complexe.

-1

si vous voulez conserver un ensemble d'initiales à utiliser plusieurs fois, ou dans le cadre d'une requête plus grande, procédez comme suit:

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 

si vous faites de lignes #temp tables sont plus rapides. En outre, il serait probablement plus rapide de simplement en faire une table dérivée dans une requête plus grande que d'utiliser une table temporaire.

+0

Une variable de table peut considérablement réduire les performances si la requête OP ne filtre pas uniquement les initiales. Dans la plupart des cas, un CTE sera meilleur, car il utilise les index de la table sous-jacente (une variable de table ne le fait pas). – richardtallent

+0

@richardtallent, lisez la question et ma réponse! J'ai dit "si vous voulez garder un ensemble d'initiales à utiliser plusieurs fois". également à partir de la question du PO il essaie de mettre les résultats dans une variable. Vous ne pouvez pas faire cela avec un CTE. Je suggérais seulement un autre type de solution! –

Questions connexes