2009-10-08 6 views
1

내 SELECT 절에 이미있는 ORDER 절에 계산식이나 하위 쿼리를 사용할 때 SQL에서 해당 열의 순서 만 알면됩니까? 또는 정렬 할 때 각 행마다 모든 항목을 다시 계산합니까? 나는,이 쿼리가 더 나은 작성하는 방법을 알고Order By 절이 SQL Server의 값을 다시 계산합니까?

SELECT EmployeeName, (SELECT COUNT(*) FROM Employee e2 WHERE MgrID = Employee.EmployeeID) 
FROM Employee 
ORDER BY (SELECT COUNT(*) FROM Employee e2 WHERE MgrID = Employee.EmployeeID) 

네 그리고 나는 나의 순서 서수를 사용하는 방법을 알고 by-- : 예를 들어

, 나는 이런 끔찍한 쿼리를 쓰고 말할 수 하지만 내가하지 않으면 어떡하지? SQL은 각 행에 대해이 하위 쿼리를 다시 실행합니까, 아니면 이미 col 2에있는 값을 사용할 수 있다는 것을 알고 있습니까?

기능을 사용하는 열에 대해 주문하는 것은 어떻습니까?

SELECT EmployeeName, LTRIM(RTRIM(BranchName)) FROM Employee 
ORDER BY LTRIM(RTRIM(BranchName)) 

내 BranchName 열을 다시 정렬하여 정렬합니까?

일부 실행 계획을 살펴 보았지만 계산을 추가하지 않은 것으로 보입니다. 그러나 이것이 내 구체적인 사례가 아닌 일반성으로 파악되는 경우 알 수 있다고 생각했습니다.

제가 주된 이유는 ROWNUMBER() OVER(ORDER BY EmployeeID)과 같은 창 작업을 수행 할 때 ORDER BY에 대한 서수 참조를 사용할 수 없다는 것입니다. 따라서 내 열 중 하나가 복잡하면 테이블 변수에 덤핑하고 다시 정렬하는 방법에 대해 논쟁하기도합니다.

답변

1

선택 개수 (*)의 표는 이 두 번으로 스캔됩니다. 주문은 한 번, 선택은 한 번. 두 하위 쿼리 등에서 상위 100 개를 사용하여 어떤 일이 발생하는지 더 자세히 말하면됩니다. 은 쿼리가 생성하는 논리적 읽기 수를 관찰합니다.

SET STATISTICS IO ON 

USE AdventureWorks 
GO 

SELECT (SELECT COUNT(*) FROM Sales.SalesOrderDetail WHERE SalesOrderID = SOH.SalesOrderID) AS c, * 
FROM Sales.SalesOrderHeader SOH 
ORDER by (SELECT COUNT(*) FROM Sales.SalesOrderDetail WHERE SalesOrderID = SOH.SalesOrderID) desc 
GO 

SELECT (SELECT COUNT(*) FROM Sales.SalesOrderDetail WHERE SalesOrderID = SOH.SalesOrderID) AS c, * 
FROM Sales.SalesOrderHeader SOH 
ORDER BY 1 desc 
+0

예, 보이는 것처럼 그것은 추가를 할 것 같습니다 (예 : EmployeeE2 WHERE MgrID = Employee.EmployeeID) 그 필드에 별칭을 지정하면 테이블을 다시 스캔 할 필요가 없습니다. MS는 윈도우 구성 요소 위에 별칭 지원 기능을 추가해야합니다! –

1
그것은, 그 자체가 별명으로 정렬 할 수 있습니다 엔진이 열을 한 번에 정렬 줄 않는 경우에만됩니다

SELECT EmployeeName, (SELECT COUNT(*) FROM Employee e2 WHERE MgrID = Employee.EmployeeID) 
FROM Employee 
ORDER BY (SELECT COUNT(*) FROM Employee e2 WHERE MgrID = Employee.EmployeeID) 

SELECT EmployeeName, (SELECT COUNT(*) FROM Employee e2 WHERE MgrID = Employee.EmployeeID) MyField 
FROM Employee 
ORDER BY myField 

과 같이 표현 될 수 엔진은 기본적으로 할 것 똑같은 일로 order by 절에서 사용할 임시 이름을 열에 제공합니다.

+0

오른쪽,하지만 난 OVER() 절 작동하도록 별칭을 확보하지 못했 :

는이 쿼리를 볼 수 있습니다. 당신은 SELECT EmployeeName과 같이, 할 수 없어 (직원 E2로부터 SELECT COUNT (*)를 WHERE MGRID = Employee.EmployeeID) MyField, ROW_NUMBER() OVER (MyField BY ORDER) (내가해야 직원 FROM ROWNUMBER 로 우리가 모두 참조 할 수있는 실제 테이블을 선택했지만 관리자가 여기에서 직장에서 삭제 한 술집) –

+0

select 절에있는 별명은 해당 select 절에서 사용할 수 없습니다. 논리적으로 select 절이 모두 있습니다. CTE 또는 인라인보기를 사용하여 필드의 이름을 지정한 다음 나중에 사용할 수 있습니다. My WHERE from Employee) T –