不使用 ORDER BY 进行排序

问题描述 投票:0回答:4

听起来有点迟钝,但这可能吗?

我有

EMPLOYEE_ID
DEPARTMENT_ID
,我必须根据
DEPARTMENT_ID
排序,而不使用
ORDER BY

它不应出现在查询中的任何位置,即在

USING
子句或 SUB-QUERY 或 SELECT 语句或任何地方。

可以吗?

sql sorting sql-order-by
4个回答
2
投票

有几种方法可以根据特定的 RDBMS 工作,但它们都不能在生产环境中使用,而只是为了好玩:

  1. 使用 XML 输出并通过
    <xsl:sort>
    应用服务器端 XSLT 转换(例如通过 CLR)。
  2. 使用存储过程在一个文本返回值中生成排序列表。
  3. 编写自己的 SQL 代理客户端,将
    -- HIDDEN MESSAGE
    替换为
    ORDER BY
    。 (我承认,这不完全是 SQL 解决方案)。
  4. 在按
    DEPARTMENT_ID
    排序的表上创建一个仅由该查询使用的索引(物化)视图。 不保证每次都有效
  5. 以增量顺序使用所有可能的 ID 创建临时表,将连接源表保留在
    DEPARTMENT_ID
    上,并使用提示来防止优化器对连接重新排序。 不保证每次都有效

Upd 6. 当要排序的行数较少时,RDBMS 支持的 CTE 递归深度:

With Example (EMPLOYEE_ID, DEPARTMENT_ID) As (
        Select 4, 2 Union All
        Select 5, 2 Union All
        Select 6, 3 Union All
        Select 7, 3 Union All
        Select 2, 1 Union All
        Select 3, 1 Union All
        Select 1, 1
    ),
    Stringified (ID) AS (
        Select
            RIGHT('0000000000' + CAST(DEPARTMENT_ID AS NVARCHAR(10)), 10) +
            RIGHT('0000000000' + CAST(EMPLOYEE_ID AS NVARCHAR(10)), 10)
        From Example
    ),
    Sorted (PREV_EMPLOYEE_ID, PREV_DEPARTMENT_ID,
            NEXT_EMPLOYEE_ID, NEXT_DEPARTMENT_ID) As (
        Select
            CAST(Right(ex1.ID, 10) AS INT),
            CAST(Left(ex1.ID, 10) AS INT),
            CAST(Right(Min(ex2.ID),10) AS INT),
            CAST(Left(Min(ex2.ID),10) AS INT)
        From Stringified ex1
        Inner Join Stringified ex2 On ex1.ID < ex2.ID
        Group By ex1.ID
    ),
    RecursiveCTE (EMPLOYEE_ID, DEPARTMENT_ID) AS (
        Select
            CAST(Right(Min(ID),10) AS INT),
            CAST(Left(Min(ID),10) AS INT)
        From Stringified
        Union All
        Select NEXT_EMPLOYEE_ID, NEXT_DEPARTMENT_ID
        From Sorted
        Inner Join RecursiveCTE
             ON RecursiveCTE.EMPLOYEE_ID = Sorted.PREV_EMPLOYEE_ID
            AND RecursiveCTE.DEPARTMENT_ID = Sorted.PREV_DEPARTMENT_ID
    )
Select *
From RecursiveCTE

Upd 7. 许多 RDBMS 引擎在应用

GROUP BY
UNION
EXCEPT
INTERSECT
或只是
DISTINCT
时会对结果进行排序,特别是当它们是单线程或强制不使用带有提示的并行性时。 不保证每次都有效


1
投票

如果您在表上创建一个索引,其中第一个(或唯一)键是

DEPARTMENT_ID
,并且您将强制查询引擎使用此索引,则这是可能的。这也应该是一个简单的
SELECT
声明。

但即便如此,也不能保证正确的排序顺序。


0
投票

也许这个链接会对你有帮助

不使用 order by 子句对结果进行排序

这就是链接所说的

你不能,至少不能可靠。

某些 SQL 实现可能会按照行的顺序返回行 主键或聚集索引,但 SQL 本身是关系型 除非特别告知,否则返回任意有序集合的代数 否则。

返回行的顺序很有可能 很大程度上取决于插入和删除活动,因为该表是 已创建。


-1
投票

您可以在不使用 ORDER BY 的情况下进行查询,将每一行放入多维数组中,然后对数组进行排序。它可以用多种语言完成。

在 PHP 中,它会是这样的:

$result = [];
// In $result you put every row from your SELECT

$aSortField = [];

    foreach ($result as $key => $row)   
        {
        $aSortField [$key] = $row['theNameOfYourSortColumn'];
        }

    array_multisort($aLocal, SORT_ASC, $result);    // This makes the "order by" job
© www.soinside.com 2019 - 2024. All rights reserved.