在SQL Server 2008 R2中更新之前排序的数据

时间:2012-11-07 13:14:02

标签: sql sql-order-by temp-tables

我在存储过程中有一个临时表。

我正在做的是从不同的表中获取数据并使用

将其插入到临时表中
INSERT INTO #TempTable
  SELECT * FROM t1
  INNER JOIN t2 ON t1.ID = t2.ID

插入后,我需要更新一列。在更新临时表之前,我想通过另一列对临时表数据进行排序。

如何在临时表的update子句之前应用ORDER By子句?

1 个答案:

答案 0 :(得分:0)

确保您的临时表具有IDENTITY字段。

CREATE TABLE #TempTable 
(
  ID int identity(1,1) primary key
  ...
)

在初次插入时点击: -

INSERT INTO 
  #TempTable
SELECT * FROM t1
INNER JOIN 
  t2 
ON t1.ID = t2.ID
ORDER BY [Your Field]

<强>原理: - 有些人可能会争辩说,将身份字段放入其中是不必要的,或者确实临时表中行的顺序并不重要。我不同意。

首先,拥有ID字段可以进行以下连接: -

SELECT 
   t1.*, t2.SpecificThing
FROM
   #TempTable t1
INNER JOIN
   #TempTable t2
ON  t1.ID = ( t2.ID + 1)

对于任何正在运行的总计/累积技巧,这都很方便。

至于在临时表中不重要的排序,我不同意 - 至少在 SQL Server 上。 SQL Server上的UPDATE语句按顺序更新行 。如果没有,这个迷人的(并且非常快速)运行的总技巧将永远不会奏效。

CREATE TABLE #CustomerInfo 
(
   ID int identity(1,1) primary key,
   CustomerId int,
   SaleValue money,
   RunningTotal money
)

-- Assume customer is populated

DECLARE @RunningTotal decimal(18,4)
DECLARE @CustomerId INT

SELECT @CustomerId = CustomerId FROM #CustomerInfo WHERE Id = 1
SET @RunningTotal = 0

-- This only works in SQL Server because under the hood, the engine is updating
-- iteratively in order.
-- 
-- Starts at row 0, then row 1 - with each row the value of @RunningTotal
-- is reassigned.
UPDATE #CustomerInfo
SET 
   @RunningTotal = 
   RunningTotal = 
   CASE WHEN 
      -- Are we still looking at the same customer?
      @CustomerId = CustomerId 
   THEN 
     -- Yes. Add sale value to @RunningTotal
     @RunningTotal + SaleValue
   ELSE
     -- No, reset @RunningTotal to SaleValue of this row
     SaleValue
   END 
   ,@CustomerId = CustomerId
 FROM #CustomerInfo