我在使用ORDER BY子句排序时遇到问题,希望有人可以帮助我弄清楚为什么排序不如预期。
我正在从多个数据库中提取数据点,并将它们添加到临时表中以在SSRS报告中输出。我还包括了一条WHILE语句,如果没有足够的记录,则可以插入NULL值以用空行填充预期的空间。
我已经更改了大多数列名以保护潜在的敏感信息,但是有问题的列是v1和ob.LineNumber。
USE db GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[db1]
@PR_ID INT
AS
BEGIN
SET NOCOUNT ON;
CREATE TABLE #temp
(v1 INT,
v2 VARCHAR(50),
v3 VARCHAR(50),
v4 VARCHAR(50),
v5 FLOAT,
v6 FLOAT,
v7 FLOAT,
v8 FLOAT,
v9 VARCHAR(50),
v10 FLOAT,
v11 VARCHAR(50),
v12 VARCHAR(50),
v13 VARCHAR(50),
v14 VARCHAR(50),
v15 FLOAT)
DECLARE @RowCount INT, @h INT
SET @RowCount = 11
INSERT INTO #temp(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
SELECT ob.LineNumber AS v1,
NULL,
NULL,
NULL,
CASE WHEN ob.Length IS NULL THEN 0 ELSE ob.Length END AS v5,
CASE WHEN ob.Width IS NULL THEN 0 ELSE ob.Width END AS v6,
CASE WHEN ob.Length IS NULL THEN 0 ELSE (ob.Length * ob.Width) END AS v7,
NULL,
sovg.Grade AS v9,
ob.AYB As v10,
ob.CC AS v11,
NULL,
NULL,
ob.PC AS v14,
ob.VT AS v15
FROM t_ob WITH (NOLOCK)
LEFT JOIN t_otpr otpr WITH (NOLOCK) ON ob.ID=otpr.ID
LEFT JOIN t_pr pr WITH (NOLOCK) ON otpr.PR_ID=pr.PR_ID
LEFT JOIN t_otb otb WITH (NOLOCK) ON ob.ID=otb.ID
LEFT JOIN t_b b WITH (NOLOCK) ON otb.B_ID=b.B_ID
LEFT JOIN t_G sovg WITH (NOLOCK) ON ob.G_ID=sovg.G_ID
WHERE pr.PR_ID = @PR_ID
ORDER BY ob.LineNumber ASC
SET @h = (SELECT COUNT(*) FROM #temp)
WHILE @h < @RowCount OR @h % @RowCount > 0
BEGIN
INSERT INTO #temp (v1) VALUES (NULL)
SET @h = @h + 1
END
SELECT * FROM #temp
END
结果如下:
v1
----------
6
2
8
9
5
4
3
7
谁能看到我要去哪里错了?
答案 0 :(得分:4)
如果您引用的是以下结果集:
SELECT * FROM #temp
然后,您做错的是假设结果集按特定顺序排列。以特定顺序获取结果集的 only 方法是为最外面的ORDER BY
包含一个明确的SELECT
子句。
答案 1 :(得分:1)
问题是ORDER BY
仅发生在INSERT上。
数据库之所以能够工作是因为关系集理论。坚持该理论的原因是可以进行许多优化和实践,使它们既可以快速查询又可以安全地同时访问。在这种情况下,数据库表是一个关系集,而关系集不是按定义排序的。
您可以按所需的任何顺序插入表中,但是该顺序无关紧要,何时该再次检索数据。为了确保获得特定的订单,在查询表时必须 声明该订单:
SELECT * FROM #temp ORDER BY v1
此外,INSERT语句末尾的ORDER BY子句没有任何功能目的,可以删除。