2009-06-05 11 views
11

puedo escribir algo como esto con LINQ:¿Puedo definir una variable en ciclo en T-SQL SELECT (como LET en LINQ)?

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

¿Puedo hacer algo similar con SQL, como podría ser:

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

pero tal vez no es un truco?

Necesito tener una variable precalculada para su uso posterior en una cláusula WHERE compleja para evitar la extrema complejidad y la repetición del código.

+2

No use 't-sql' para una etiqueta - use 'tsql' en su lugar. Preste atención a las sugerencias al etiquetar su pregunta, cualquier etiqueta con un número <10 después de que probablemente deba evitarse el nombre. –

+0

¿Por qué? "T-SQL" se usa normalmente pero no TSQL. – User

+0

@Mastermind, desafortunadamente, más personas utilizaron históricamente tsql, por lo que volvemos a etiquetarlas para garantizar la coherencia. –

Respuesta

12

Una forma limpia de hacer esto sin agregar una tabla temporal, bucles, etc. sería con una expresión de tabla común (CTE). Ejemplo:

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

En lugar del vacío '' anterior, se puede utilizar un punto o algo más para sustituir a los campos de nombres nulos.

todo esto debe ser ejecutado en una sola llamada de SQL .NET - el CTE no se guarda en la base de datos como una vista, procedimiento almacenado, tabla temporal, etc.

+0

tendría que probar para casos NULOS – van

+2

OP dice "Necesito tener una variable precalculada para su uso posterior en una cláusula WHERE compleja". de su pregunta, parece que quieren almacenar los resultados en una variable, no solo devolver un conjunto de resultados de una sola vez. Si no, entonces esta es una buena respuesta, de lo contrario deben verificar mi respuesta ... –

+2

-1 esto no es lo que el operador está preguntando si lo entiendo. – JoshBerke

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

o

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

Si necesita usarlo más tarde, una forma claramente legible es utilizar un exprssion mesa común (que se pueden apilar, en lugar de anidada):

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

Parece que está tratando de obtener las iniciales en una variable para más adelante. Trate de esta manera ...

DECLARE @Initials varchar(2) 

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

Si usted está tratando de usar eso como un conjunto y no un solo valor, usted debe buscar en hacer una subconsulta o CTE con la otra consulta compleja.

-1

si desea mantener un conjunto de iniciales a utilizar varias veces, o como parte de una consulta grande, haga lo siguiente:

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 están haciendo muchas filas #temp tablas son más rápidos. Además, probablemente sería más rápido hacer de esto una tabla derivada en una consulta más grande que usar una tabla temporal.

+0

Una variable de tabla puede obstaculizar drásticamente el rendimiento si la consulta del OP filtra más que solo las iniciales. En la mayoría de los casos, un CTE será mejor, ya que utiliza los índices de la tabla subyacente (una variable de tabla no). – richardtallent

+0

@richardtallent, lea la pregunta y mi respuesta! Dije "si quieres mantener un conjunto de iniciales para usar varias veces". también de la pregunta del OP está tratando de poner los resultados en una variable. No puedes hacer eso con un CTE. ¡Solo estaba sugiriendo un tipo diferente de solución! –

Cuestiones relacionadas