2011-05-19 21 views
2

我有一个表,看起来像这样SQL:制作一个“计算列”

TYPE | A | B | C | ... | Z 
one | 4 | 4 | 4 | ... | 4 
two | 3 | 2 | 2 | ... | 1 

,我想插入与计算的行(行一分减排二):

TYPE | A | B | C | ... | Z 
one | 4 | 4 | 4 | ... | 4 
two | 3 | 2 | 2 | ... | 1 
delta| 1 | 2 | 2 | ... | 3 

我在想一个SQL命令看起来像

(select A from table where type=one) - (select A from table where type=two) 

不好的一面是,它太长时间,我也必须这样做对所有列(AZ)的这是相当多的。

我相信有这样做的更优雅的方式。

PS:

我的代码序列看起来像这样BTW:

// I'm inserting the data from a RawTable to a TempTable 

INSERT one 
INSERT two 
INSERT delta 
INSERT three 
INSERT four 
INSERT delta 
... 
INSERT onehundredone 
INSERT onehundredtwo 
INSERT delta 
+0

想必,你不想来存储这些数据,只是将其包含在结果组?另外,我认为你的编号已经在'...'中消失了,因为如果你正在配对工作,那么'one one'和'one two'应该是一对。 – 2011-05-19 13:32:44

+0

我将它存储到一个临时表,然后将其绑定到一个gridview。是的,它应该是102,我只是表明强调行数。 – 2011-05-19 13:36:07

+0

听起来像是一个用户界面问题...您可能可以在SQL中执行此操作(您没有提及您使用的是哪种SQL产品或版本),但如果您将数据网格扩展为执行操作你想要什么。 – 2011-05-19 13:53:14

回答

3

我与identity添加了ID列到你的临时表。你可以用它来确定哪些行应该分组。

create table YourTable 
(
    ID int identity primary key, 
    [TYPE] varchar(20), 
    A int, 
    B int, 
    C int 
) 

insert into YourTable ([TYPE], A, B, C) 
select 'one', 4, 4, 4 union all 
select 'two', 3, 2, 2 union all 
select 'three', 7, 4, 4 union all 
select 'four', 3, 2, 2 union all 
select 'five', 8, 4, 4 union all 
select 'six', 3, 2, 2 


select T.[TYPE], T.A, T.B, T.C 
from 
    (
    select 
     T.ID, 
     T.[TYPE], 
     T.A, 
     T.B, 
     T.C 
    from YourTable as T 
    union all 
    select 
     T2.ID, 
     'delta' as [TYPE], 
     T1.A-T2.A as A, 
     T1.B-T2.B as B, 
     T1.C-T2.C as C 
    from YourTable as T1 
     inner join YourTable as T2 
     on T1.ID = T2.ID-1 and 
      T2.ID % 2 = 0 
) as T 
order by T.ID, case T.[TYPE] when 'delta' then 1 else 0 end 

结果:

TYPE     A   B   C 
-------------------- ----------- ----------- ----------- 
one     4   4   4 
two     3   2   2 
delta    1   2   2 
three    7   4   4 
four     3   2   2 
delta    4   2   2 
five     8   4   4 
six     3   2   2 
delta    5   2   2 

排序上C列从第一行中的组:

select T.[TYPE], T.A, T.B, T.C 
from 
    (
    select 
     T1.ID, 
     T1.[TYPE], 
     case T1.ID % 2 when 1 then T1.C else T2.C end as Sortorder, 
     T1.A, 
     T1.B, 
     T1.C 
    from YourTable as T1 
     left outer join YourTable as T2 
     on T1.ID = T2.ID+1 
    union all 
    select 
     T2.ID, 
     'delta' as [TYPE], 
     T1.C as Sortorder, 
     T1.A-T2.A as A, 
     T1.B-T2.B as B, 
     T1.C-T2.C as C 
    from YourTable as T1 
     inner join YourTable as T2 
     on T1.ID = T2.ID-1 and 
      T2.ID % 2 = 0 
) as T 
order by T.Sortorder, T.ID, case T.[TYPE] when 'delta' then 1 else 0 end 
+0

加上一个让它发现! – 2011-05-19 20:59:28

+0

辉煌,谢谢 – 2011-05-20 01:37:15

+0

我可以问你另外一个问题,是否可以根据该组的“C列”和“行1”的值对组“(一,二,三角洲)”进行排序? – 2011-05-20 01:41:06

1

我不知道有什么方法可以做到这一点“轻松地”(即无需指定每一列) ,我不能想出任何方法来做到这一点,所以我会记录下来,说它不能做到。容易。

非简单的方法是构建动态代码 - 通过数据库元数据循环,构建一个包含语句的字符串以逐列执行所需的例程,然后执行该字符串。你真的想尽可能避免这种情况。

一个快捷方式,如果您只需要构建一个可以执行此操作的过程或函数(即构建一次运行很多),则可以将列表复制到电子表格(Excel)中,使用高级重复性语句构建高度重复的语句参考列名称的论坛,然后将结果复制回来。 (这是简单得多做的比它要解释的。)

1

我不知道你为什么这样做,但我想接近它的方法是:

insert into table 
select 'delta', 
t1.a - t2.a, 
t1.b - t2.b 
..... 
from table t1, 
table t2 
where t1.type = 'one' 
and t2.type = 'two' 

你将不得不插入“one”和“two”后立即运行此查询,然后在插入“three”和“four”后重新运行它。讨厌讨厌。

如果您可以以某种方式重新命名列,或创建数字列,则可以在单个查询中运行它。

+0

这是因为我必须展示一个看起来像这样的报告。从数据库获得配对,然后显示增量。然后为其余的做同样的事情。所以我要做的是将它全部存储在临时表中,然后将其绑定到单个gridview。或者,还有更好的方法? – 2011-05-19 14:14:25

+0

那么,你可以在前端做 - 但你的解决方案听起来像其他任何合理的......你需要想出一个方法来排序结果集,并将“delta”行插入到正确的位置。 – 2011-05-19 15:01:01

0

当您更换一个1,二为2,以此类推,那么也许这个SQL可以工作:

INSERT INTO PodMays 
SELECT 
    "Delta", A.A-B.A, A.B-B.B, A.C-B.C, A.D-B.D, A.E-B.E 
FROM 
    (
    SELECT TOP 1 
     * 
    FROM 
     (SELECT TOP 2 * FROM PodMays WHERE Type <> "Delta" ORDER BY Type DESC) 
    ORDER BY 
     Type ASC 
) AS A, 
    (
    SELECT TOP 1 
     * 
    FROM 
     (SELECT TOP 2 * FROM PodMays WHERE Type <> "Delta" ORDER BY Type DESC) 
    ORDER BY 
     Type DESC 
) AS B