Использование полей выбора в других вычисляемых полях в SQL Server - PullRequest
0 голосов
/ 23 декабря 2009

У меня есть таблица со столбцами A, B и C, и я хочу выбрать из этой таблицы, но с некоторыми дополнительными полями, вычисленными из A, B и C и другими вычисляемыми полями. Например:

  • D = A * B + C
  • E = 2 * D + 4 * A
  • F = D * D * E

Я думал, что смогу решить это так:

select A, B, C, (A * B + C) as D, (2 * D + 4 * A) as E, (D * D * E) as F
from Table

Но это приводит к ошибке: SQL Server не позволяет мне использовать D в выражении для E.

Я придумал два способа обойти это:

  1. Я расширяю использование D в E и F и использование D и E в F до их полных определений, например. (2 * (A * B + C) + 4 * A) as E, ((A * B + C) * (A * B + C) * (2 * (A * B + C) + 4 * A)) as F
  2. Используйте подзапросы так:

    select A, B, C, D, E, (D * D * E) as F
    from (
        select A, B, C, D, (2 * D + 4 * A) as E
        from (
            select A, B, C, (A * B + C) as D
          ) as UpToD
      ) as UpToE
    

Ни одно из решений не является удовлетворительным: в случае 1 запрос становится неуправляемо длинным, и всякий раз, когда я изменяю способ вычисления поля, все поля, которые зависят от него, должны обновляться. Рекурсивный. В случае 2 ситуация немного лучше, но все еще неудобно создавать подзапрос для каждого нового поля, которое я хочу вычислить, и мне нужно многократно перечислять все имена полей.

Как лучше всего выразить этот запрос?

Заранее спасибо!

Ответы [ 2 ]

2 голосов
/ 23 декабря 2009

Я бы предложил использовать функции

CREATE FUNCTION D 
(
    @A int,
    @B int,
    @C int
)
RETURNS int
AS
BEGIN
    RETURN @A + @B + @C
END
GO

create table test (A int null, B int null, C int  null)
insert into test (A,B,C) values(1,2,3)

select A,B,C,dbo.D(1,2,3) as D from test
1 голос
/ 23 декабря 2009

Хотя я уверен, что некоторые люди могут нахмуриться, я бы выбрал вариант 2, но перефразировал это так:

select UpToE.*, (D * D * E) as F
from (
    select UpToD.*, (2 * D + 4 * A) as E
    from (
        select A, B, C, (A * B + C) as D
      ) as UpToD
  ) as UpToE

Это немного чище, потому что вы не повторяете одни и те же основные колонки снова и снова. Я знаю, что некоторые люди недовольны использованием * внутри выбора, но, поскольку вы явно определяете свои столбцы в фактическом выборе из таблицы (самый внутренний подзапрос), вы не столкнетесь с проблемами при изменении базовой таблицы. .

Я не уверен, будет ли это влиять на производительность, чтобы знать об этом.

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