听起来有点迟钝,但这可能吗?
我有
EMPLOYEE_ID
和DEPARTMENT_ID
,我必须根据DEPARTMENT_ID
排序,而不使用ORDER BY
。
它不应出现在查询中的任何位置,即在
USING
子句或 SUB-QUERY 或 SELECT 语句或任何地方。
可以吗?
有几种方法可以根据特定的 RDBMS 工作,但它们都不能在生产环境中使用,而只是为了好玩:
<xsl:sort>
应用服务器端 XSLT 转换(例如通过 CLR)。-- HIDDEN MESSAGE
替换为 ORDER BY
。 (我承认,这不完全是 SQL 解决方案)。DEPARTMENT_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
时会对结果进行排序,特别是当它们是单线程或强制不使用带有提示的并行性时。 不保证每次都有效。
如果您在表上创建一个索引,其中第一个(或唯一)键是
DEPARTMENT_ID
,并且您将强制查询引擎使用此索引,则这是可能的。这也应该是一个简单的 SELECT
声明。
但即便如此,也不能保证正确的排序顺序。
也许这个链接会对你有帮助
这就是链接所说的
你不能,至少不能可靠。
某些 SQL 实现可能会按照行的顺序返回行 主键或聚集索引,但 SQL 本身是关系型 除非特别告知,否则返回任意有序集合的代数 否则。
返回行的顺序很有可能 很大程度上取决于插入和删除活动,因为该表是 已创建。
您可以在不使用 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