尝试通过声明数据在T-SQL中排序时出错

时间:2019-02-28 01:28:58

标签: sql-server tsql sorting

我正在尝试学习T-SQL编程,但我发现下面的代码有错误。该代码用于学习如何不按顺序进行排序,它看起来像气泡排序算法。

我首先创建表格并尝试进行排序后插入随机数

代码:

CREATE TABLE #NumbersArray
(
    ArrayIndex INT PRIMARY KEY,
    Value INT
)
GO

INSERT INTO #NumbersArray(ArrayIndex, Value)
    SELECT 0, 5
    UNION ALL
    SELECT 1, 1 
    UNION ALL
    SELECT 2, 3 
    UNION ALL
    SELECT 3, 4
    UNION ALL
    SELECT 4, 2

SELECT * FROM #NumbersArray
GO    

DECLARE @CurrentIndex INT,
        @MaxIndex INT,
        @swapoccured BIT

SET @swapoccured = 1
SET @MaxIndex = (SELECT COUNT(*) - 1 FROM #NumbersArray)

WHILE (@swapoccured = 1)
BEGIN
    SET @swapoccured = 0
    SET @CurrentIndex = 0

    WHILE (@CurrentIndex < @MaxIndex)
        DECLARE @value1 INT
        DECLARE @value2 INT
    BEGIN  -- Mistake was here. I put the begin in wrong place
        SET @value1 = (SELECT Value FROM #NumbersArray WHERE ArrayIndex = @CurrentIndex)
        SET @value2 = (SELECT Value FROM #NumbersArray WHERE ArrayIndex = @CurrentIndex + 1)

        IF (@value1 > @value2)
        BEGIN
            UPDATE #NumbersArray 
            SET Value = @value2 
            WHERE ArrayIndex = @CurrentIndex

            UPDATE #NumbersArray 
            SET Value = @value1 
            WHERE ArrayIndex = @CurrentIndex + 1

            SET @swapoccured = 1
         END

         SET @CurrentIndex = @CurrentIndex + 1
    END
END

SELECT * FROM #NumbersArray

所以我认为我的代码排在第二个排序的中间,因为我的代码从未完成,但是我可以确定问题所在。

2 个答案:

答案 0 :(得分:3)

  

此代码用于学习如何按...进行无序排序...

嗯,那根本不可能做到。 在关系数据库中,表本质上是未排序的。确保查询返回的结果顺序的唯一方法是使用order by子句。

  

我正在尝试学习T-SQL编程

了解SQL的任何方言的第一件事是,它旨在与基于集合的方法一起使用-意味着操作是在行集上完成的,而不是基于过程的方法(又名to_timedelta-通过苦苦挣扎来生。)
您可以搜索“基于集合还是过程”,并找到许多文章,详细说明这些方法之间的区别。

因此,话虽这么说-在SQL世界中不鼓励使用循环(甚至包括嵌套循环)-包括游标,while循环甚至递归公用表表达式。
在大多数情况下,您可以通过使用RBAR来避免使用循环-使用基于集的方法来更改RBAR方法,并使您的代码更高效,并且在大多数情况下更易于编写,读取和维护。 / p>

答案 1 :(得分:1)

首先,没有ORDER BY子句就不可能对数据进行排序(请阅读@ZoharPeled的回答),因此这不是合适的方法。这样,我将只关注您的错误。原因是第二个WHILE循环。如果没有BEGIN .. END,则此循环将无限地声明一个变量:WHILE (@CurrentIndex < @MaxIndex) DECLARE @value1 INT

这可能是您想要的(仅用于学习如何使用WHILE循环,而不是如何订购数据):

CREATE TABLE #NumbersArray
(
    ArrayIndex INT PRIMARY KEY,
    Value INT
)
GO

INSERT INTO #NumbersArray(ArrayIndex, Value)
    SELECT 0, 5
    UNION ALL
    SELECT 1, 1 
    UNION ALL
    SELECT 2, 3 
    UNION ALL
    SELECT 3, 4
    UNION ALL
    SELECT 4, 2

SELECT * FROM #NumbersArray
GO    

DECLARE @CurrentIndex INT,
        @MaxIndex INT,
        @swapoccured BIT

SET @swapoccured = 1
SET @MaxIndex = (SELECT COUNT(*) - 1 FROM #NumbersArray)

WHILE (@swapoccured = 1)
BEGIN
    SET @swapoccured = 0
    SET @CurrentIndex = 0

    DECLARE @value1 INT
    DECLARE @value2 INT
    WHILE (@CurrentIndex < @MaxIndex)
    BEGIN
        SET @value1 = (SELECT Value FROM #NumbersArray WHERE ArrayIndex = @CurrentIndex)
        SET @value2 = (SELECT Value FROM #NumbersArray WHERE ArrayIndex = @CurrentIndex + 1)

        IF (@value1 > @value2)
        BEGIN
            UPDATE #NumbersArray 
            SET Value = @value2 
            WHERE ArrayIndex = @CurrentIndex

            UPDATE #NumbersArray 
            SET Value = @value1 
            WHERE ArrayIndex = @CurrentIndex + 1

            SET @swapoccured = 1
         END

         SET @CurrentIndex = @CurrentIndex + 1
    END
END

SELECT * FROM #NumbersArray

DROP TABLE #NumbersArray