这是一种愚蠢的方式来排序几个值?

时间:2013-08-25 00:32:13

标签: tsql sorting

我正在检查事物的尺寸,我想知道从最大到最小的3个维度。

所以这就是我写的那种'眩晕功能:

CREATE FUNCTION dbo.SortDimensions
    ( @aDim1 udt_Dimension
    , @aDim2 udt_Dimension
    , @aDim3 udt_Dimension 
    )
RETURNS @rDimensions TABLE 
    ( Dim1 udt_Dimension
    , Dim2 udt_Dimension
    , Dim3 udt_Dimension 
    )
AS
BEGIN
  ; WITH OrderedDims ( Dimension ) AS ( 
                SELECT @aDim1
      UNION ALL SELECT @aDim2
      UNION ALL SELECT @aDim3
   )
  ,      Pairs ( Name, Value ) AS ( 
      SELECT 'Dim' + CAST( ROW_NUMBER() OVER (ORDER BY( Dimension ) DESC ) AS varchar ), Dimension 
        FROM OrderedDims 
  )
  INSERT INTO @rDimensions ( Dim1, Dim2, Dim3 )
      SELECT MAX(Dim1), MAX(Dim2), MAX(Dim3) 
        FROM Pairs 
      PIVOT ( MAX(Value) FOR Name IN ( [Dim1], [Dim2], [Dim3] )) p

  RETURN
END

对于做同样的事情,这不是很多工作:

DECLARE @lDim1 udt_Dimension
DECLARE @lDim2 udt_Dimension 
DECLARE @lDim2 udt_Dimension

IF @aDim2 > @aDim1 
  BEGIN
    SELECT @lDim1 = @aDim2 
         , @lDim2 = @aDim1
  END
ELSE 
  BEGIN 
    SELECT @lDim1 = @aDim1 
         , @lDim2 = @aDim2
  END

IF NOT @aDim3 > @aDim2 
  BEGIN 
    SET @lDim3 = @aDim3
  END
ELSE
  BEGIN
    SET @lDim3 = @lDim2
    IF @aDim3 > @lDim1 
      BEGIN
        SET @lDim2 = @lDim1
        SET @lDim1 = @aDim3
      END
    ELSE 
      BEGIN
        SET @lDim2 = @aDim3
      END
  END 

INSERT INTO @rDimensions VALUES ( @lDim1, @lDim2, @lDim3 )

我相信DBA曾经告诉我,设计SQL服务器的人重复使用临时表技术来处理变量,所以它几乎是表和变量之间的冲突。 (如果不是这样的话,那就去解除这个想法吧。)

1 个答案:

答案 0 :(得分:1)

我很确定这应该更快:

CREATE FUNCTION dbo.SortDimensions
    ( @aDim1 udt_Dimension
    , @aDim2 udt_Dimension
    , @aDim3 udt_Dimension 
    ) RETURNS TABLE
AS RETURN
(
    WITH cte As (     SELECT @aDim1 As Dim
            UNION All SELECT @aDim2
            UNION ALL SELECT @aDim3
    )
    , cte2 As ( SELECT Dim, ROW_NUMBER() OVER(ORDER BY Dim) As Odr FROM cte )
    SELECT  
            MAX(CASE WHEN Odr=1 THEN Dim ELSE NULL END) As Dim1,
            MAX(CASE WHEN Odr=2 THEN Dim ELSE NULL END) As Dim2,
            MAX(CASE WHEN Odr=3 THEN Dim ELSE NULL END) As Dim3
    FROM    cte2
)