Могу ли я определить переменную в цикле в T-SQL SELECT (как LET в LINQ)? - PullRequest
11 голосов
/ 05 июня 2009

Я могу написать что-то подобное с помощью LINQ:

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

Могу ли я сделать что-то похожее с SQL, например:

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

Наверное, нет, но, может быть, есть хитрость?

Мне нужна предварительно вычисленная переменная для дальнейшего использования в сложном предложении WHERE, чтобы избежать чрезвычайной сложности и повторения кода.

Ответы [ 4 ]

13 голосов
/ 05 июня 2009

Чистый способ сделать это без добавления временной таблицы, циклов и т. Д. Был бы с помощью Common Table Expression (CTE). Пример:

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

Вместо пустого '' вы можете использовать точку или что-то еще, чтобы заменить поля с нулевым именем.

Все это должно выполняться за один вызов SQL из .NET - CTE не сохраняется в базе данных, как представление, хранимая процедура, временная таблица и т. Д.

3 голосов
/ 05 июня 2009

Похоже, вы просто пытаетесь получить инициалы в переменную на потом. Попробуйте это так ...

DECLARE @Initials varchar(2)

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

Если вы пытаетесь использовать это как набор, а не как одно значение, вы должны посмотреть на выполнение подзапроса или CTE с другим сложным запросом.

2 голосов
/ 05 июня 2009
SELECT Initials
    = SUBSTRING (Person.FirstName, 1, 1)
      + SUBSTRING (Person.LastName, 1, 1)
FROM [Person]

или

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

Если вам понадобится использовать его позже, ясно читаемый способ - использовать общее выражение таблицы (которое может быть сложено, а не вложено):

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
0 голосов
/ 05 июня 2009

, если вы хотите сохранить набор инициалов для многократного использования или как часть более крупного запроса, выполните следующие действия:

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

если вы делаете много строк, таблицы #temp работают быстрее. Кроме того, вероятно, было бы быстрее сделать эту производную таблицу большим запросом, чем использовать временную таблицу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...