【问题标题】:dynamic operations with 2 tables and 1 insert SQL Server具有 2 个表和 1 个插入 SQL Server 的动态操作
【发布时间】:2011-02-28 22:17:47
【问题描述】:

我有 2 张桌子:

表1

id someval someatt
-------------------
1      23   name1
2      56   name2
3      76   name3
4     456   name4
5      53   name5
6      67   name6
7      12   name7
8      43   name8
9      99   name9
10    567   name10

表2

    id someval someatt
    -------------------
    1     23.3   name1
    2     5.6    name2
    3     8.76   name3
    4     4.56   name4
    5      5.3   name5
    6      6.7   name6
    7      1.2   name7
    8      4.3   name8
    9      9.9   name9
    10    56.7   name10

我需要在一个新表中插入两个表的各个字段的一些操作,例如

iteration1
x = get value from table1 where id 1 
y = get value from table1 where id 2
a = get value from table2 where id 1
b = get value from table2 where id 2

iteration2
r =  get value from table1 where id 2
s =  get value from table1 where id 3
u = get value from table2 where id 2
v = get value from table2 where id 3


iterationn.
q =  get value from table1 where id n-1
p =  get value from table1 where id n
o = get value from table2 where id n-1
e = get value from table2 where id n

然后插入NEWTABLE

(a*b + x+y), (r*s + u*v) ...(q*p+o*e) 

所以我在想(如果我必须这样做 100 次):

SET @counter  = 1;
SET @template = '';
SET @N = 100;
WHILE(@counter < @N)
  Select @x =  value from table 1 where id = @counter
  Select @y =  value from table 1 where id = @counter + 1
  Select @a =  value from table 2 where id = @counter
  Select @b =  value from table 2 where id = @counter + 1
  @template = @template + ' (@x*@y + @a*@b), '
end

所以在循环结束时我有一个完整的模板

然后是EXEC(@template)

  • 如何优化它?
  • 如何执行我描述的操作? (table1 和 table2 是我的表的示例)
  • 有没有办法 4选 避免陈述?

输出表:

result1  result2 result3 .... result100
---------------------------------------
 float     float   float  ...    float   

其中 float 是针对 table1 和 table2 中的每个值计算 (a*b + x+y) 的结果

【问题讨论】:

  • 为什么要水平显示结果?应用程序比数据库层更好地处理。
  • 好吧,原因是我会按照描述的方式插入结果,我会得到一个有 100 列和 n 行的表,其中一行按描述计算
  • 您提供的代码只计算单行。你的意思是你会一遍又一遍地重复EXEC(@template),直到你只剩下一个值?
  • 不是EXEC(@template),模板将改变并从其他表中获取其他值并继续插入new table

标签: sql sql-server tsql


【解决方案1】:

这将适用于 SQL 2005 及更高版本,使用您列出的相同数据。

SELECT  t1x.id AS smaller_id,
        ( t1x.someval * t1y.someval ) + ( t2a.someval * t2b.someval ) AS result
FROM    dbo.table1 AS t1x
        INNER JOIN dbo.table1 AS t1y ON t1x.id + 1 = t1y.id
        INNER JOIN dbo.table2 AS t2a ON t2a.id = t1x.id
        INNER JOIN dbo.table2 AS t2b ON t2b.id = t1y.id

如果您希望它是水平的,则必须对结果进行 PIVOT。

SELECT  'Calculation Result' AS CalcRes,
        [result1], [result2], [result3], [result4], [result5], [result6], [result7], [result8], [result9]
FROM    (
            SELECT  'result' + cast(t1x.id AS varchar(4)) AS result_name, 
                    ( t1x.someval * t1y.someval ) + ( t2a.someval * t2b.someval ) AS result
            FROM    dbo.table1 AS t1x
                    INNER JOIN dbo.table1 AS t1y ON t1x.id + 1 = t1y.id
                    INNER JOIN dbo.table2 AS t2a ON t2a.id = t1x.id
                    INNER JOIN dbo.table2 AS t2b ON t2b.id = t1y.id
        ) AS Results
PIVOT (
    min( result ) --there needs to be an aggregate function here
    FOR result_name IN ([result1], [result2], [result3], [result4], [result5], [result6], [result7], [result8], [result9])
) AS PivotedResults

您需要为此使用动态 SQL,因为您需要在透视之前知道结果列的名称。

【讨论】:

    【解决方案2】:

    将所有记录连接在一起:

    insert
        NEWTABLE (theid, newval)
    select
        t1_p.id as theid
        (t2_p.someval * t2_n.someval) + (t1_p.someval * t1_n.someval) as newval
    from
        Table1 t1_p
    inner join
        Table1 t1_n on t1_p.id + 1 = t1_n.id
    inner join
        Table2 t2_p on t1_p.id = t2_p.id
    inner join
        Table2 t2_n on t1_n.id = t2_n.id
    

    【讨论】:

    • 所以如果现在我必须这样做 100 次并将每个结果插入到一个新表中,查询看起来如何?动态 SQL?
    • @darkcminor:不,您只会运行此查询一次。它对单个查询中的所有 (100+) 行执行操作。更新了一个如何插入的示例。
    • @darkcminor:您能提供一个示例输出 NEWTABLE 应该是什么样子吗?那我也可以给出更具体的答案。
    【解决方案3】:

    不确定我是否完全理解您的问题,但是......

    ;with cte1 as
    (
      select
        T1_1.id,
        T1_1.someval as x,
        T1_2.someval as y
      from @T1 as T1_1
        inner join @T1 as T1_2
          on T1_1.id = T1_2.id-1
    ),
    cte2 as
    (
      select
        T2_1.id,
        T2_1.someval as a,
        T2_2.someval as b
      from @T2 as T2_1
        inner join @T2 as T2_2
          on T2_1.id = T2_2.id-1
    )
    select (a*b + x*y)
    from cte1 as T1
      inner join cte2 as T2
        on T1.id = T2.id
    

    【讨论】:

      【解决方案4】:

      你可以试试类似的东西

          INSERT INTO SomeTable
          SELECT
              (x.value * y.value) + (a.value * b.value)
          FROM
              Table1 x 
              Table1 y on y.id = x.id + 1
              Table2 a on a.id = x.id
              Table2 b on b.id = x.id + 1
          WHERE
              x.Id = @counter
      

      【讨论】:

      • 一个问题...在您的查询中,@counter 变量是如何递增的,如果让我们说 @counter 依赖于另一个变量???
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-18
      • 1970-01-01
      • 1970-01-01
      • 2019-01-19
      • 1970-01-01
      • 2018-03-20
      • 2014-04-14
      相关资源
      最近更新 更多