2009-12-23 60 views
0

我有一个列A,B和C的表,我想从该表中选择,但从A,B和C以及其他计算字段计算出一些附加字段。例如:在SQL Server中使用其他计算字段中的选择字段

  • 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,查询变得unmanagably长,每当我改变字段的计算方式,各个领域依赖它需要更新。递归。在情况2中,情况稍微好一点,但为我想计算的每个新字段创建一个子查询仍然感觉很尴尬,我需要重复列出所有字段名称。

表达此查询的最佳方式是什么?

在此先感谢!

+1

我更喜欢#2,您也可避免多次通过明智地使用*的(我认为是站不住脚这里) – AakashM 2009-12-23 15:03:09

回答

1

虽然我敢肯定,有些人可能会皱眉就可以了,我会去与选项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 

它在干净了一点你不重复相同的核心一遍又一遍的列。我知道有些人在select中使用*时不满意,但是由于您在表中实际选择(最内部子查询)时明确定义了列,所以当基础表发生更改时,您不会遇到问题。

我不确定这是否会有任何性能影响,但要注意。

+0

感谢列出字段名。现在它告诉我,为什么SQL Server的文档感觉需要提到最大子查询深度是32. :-) – Martijn 2009-12-23 15:04:30

+0

接受这个答案,因为这是我最后去的那个。再次感谢! – Martijn 2010-01-21 15:16:04

2

我会建议使用功能

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