[SQL] 왜 절 곳에서 함수, 윈도우를하지?
SQL왜 절 곳에서 함수, 윈도우를하지?
내가 SQL Server에서 where 절에서 윈도우 기능을 사용할 수 없습니다 왜 제목은 모두 그것을 말한다?
이 쿼리는 완벽한 의미가 있습니다 :
select id, sales_person_id, product_type, product_id, sale_amount
from Sales_Log
where 1 = row_number() over(partition by sales_person_id, product_type, product_id order by sale_amount desc)
그러나 그것은 작동하지 않습니다. CTE를 / 하위 쿼리보다 더 좋은 방법이 있나요?
편집하다
어떻게 그 가치를 들면 이것은 CTE와 쿼리는 다음과 같습니다
with Best_Sales as (
select id, sales_person_id, product_type, product_id, sale_amount, row_number() over (partition by sales_person_id, product_type, product_id order by sales_amount desc) rank
from Sales_log
)
select id, sales_person_id, product_type, product_id, sale_amount
from Best_Sales
where rank = 1
편집하다
하위 쿼리와 함께 보여주는 답변 +1,하지만 정말 뒤에 추론을 찾고 있어요는 조항 곳에서 기능을 윈도 사용할 수없는.
해결법
-
==============================
1.특히 유익한 것은 아니지만 사양은 당신이 할 수없는 것을 말한다 때문에 한 대답은,이다.
특히 유익한 것은 아니지만 사양은 당신이 할 수없는 것을 말한다 때문에 한 대답은,이다.
Itzik 벤 웨이 코 뮤니시에 의한 기사 참조 - 논리 질의 처리를 : 그것은이고 당신과 이미지 여기에 특히 무엇 그것은 무엇을 의미하는지. 윈도우 함수 / 조인 WHERE 모든 / GROUP BY가 / HAVING 절이 (단계 5.1)로 처리 한 후 남아있는 결과 세트에 SELECT시 평가된다.
그들은 WHERE 절에서 허용되지 않습니다 이유는 모호성을 만들 것입니다. 윈도우 기능을 사용하여 고성능 T-SQL에서 Itzik 벤 웨이 코 뮤니시의 예를 훔치는 (P.25)
테이블이었다 가정
CREATE TABLE T1 ( col1 CHAR(1) PRIMARY KEY ) INSERT INTO T1 VALUES('A'),('B'),('C'),('D'),('E'),('F')
그리고 쿼리
SELECT col1 FROM T1 WHERE ROW_NUMBER() OVER (ORDER BY col1) <= 3 AND col1 > 'B'
올바른 결과는 무엇일까요? 당신이 기대할 수있는 COL1이> 'B'술어 실행하기 전에 또는 행 번호 매기기 후?
-
==============================
2.CTE, 그냥 서브 쿼리의 윈도 기능을 사용할 필요가 없습니다 :
CTE, 그냥 서브 쿼리의 윈도 기능을 사용할 필요가 없습니다 :
select id, sales_person_id, product_type, product_id, sale_amount from ( select id, sales_person_id, product_type, product_id, sale_amount, row_number() over(partition by sales_person_id, product_type, product_id order by sale_amount desc) rn from Sales_Log ) sl where rn = 1
편집 대답에 내 의견을 이동.
데이터가 실제로 WHERE 절 뒤에있는 선택 될 때까지 윈도 함수가 수행되지 않는다. 당신이 값이 아직 할당되지 않은 WHERE 절에 ROW_NUMBER를 사용하려고한다면.
-
==============================
3.우선 그것의 무언가를 한꺼번에 작업을 호출
우선 그것의 무언가를 한꺼번에 작업을 호출
그리고 윈도우 기능에 큰 장 영향 :
당신이 가정 :
CREATE TABLE #Test ( Id INT) ; INSERT INTO #Test VALUES ( 1001 ), ( 1002 ) ; SELECT Id FROM #Test WHERE Id = 1002 AND ROW_NUMBER() OVER(ORDER BY Id) = 1;
사례 1 :
(ID = 1002) 제 경우, 만약 (ROW_NUMBER () OVER (ORDER BY 이드) = 1)
결과 : 1002
사례 2 :
(ROW_NUMBER () OVER (ORDER BY 아이디) = 1), 다음 경우에 선택하면 (= 1002 Id)을
결과 : 비어
추가
테라 데이타 지원 절 자격 :
SELECT Id FROM #Test WHERE Id = 1002 QUALIFY ROW_NUMBER() OVER(ORDER BY Id) = 1;
부록 2 :
-
==============================
4.당신은 반드시 CTE를 사용할 필요가 없습니다, 당신은) (ROW_NUMBER 사용 후 결과 세트를 조회 할 수 있습니다
당신은 반드시 CTE를 사용할 필요가 없습니다, 당신은) (ROW_NUMBER 사용 후 결과 세트를 조회 할 수 있습니다
select row, id, sales_person_id, product_type, product_id, sale_amount from ( select row_number() over(partition by sales_person_id, product_type, product_id order by sale_amount desc) AS row, id, sales_person_id, product_type, product_id, sale_amount from Sales_Log ) a where row = 1
-
==============================
5.마지막으로, 구식, 이전 SQL Server 2005의 방법은 상관 하위 쿼리와 함께있다 :
마지막으로, 구식, 이전 SQL Server 2005의 방법은 상관 하위 쿼리와 함께있다 :
select * from Sales_Log sl where sl.id = ( Select Top 1 id from Sales_Log sl2 where sales_person_id = sl.sales_person_id and product_type = sl.product_type and product_id = sl.product_id order by sale_amount desc )
나는 단지 완전성을 위해서 당신이를 제공합니다.
-
==============================
6.그것은 오래 된 스레드,하지만 내가 특별히 주제에 표현 된 질문에 대한 답변을 찾아보십시오.
그것은 오래 된 스레드,하지만 내가 특별히 주제에 표현 된 질문에 대한 답변을 찾아보십시오.
SELECT 문은 주문에서 키 입력에 지정된 주요 절을 다음과 같은있다 :
SELECT DISTINCT TOP list FROM JOIN ON / APPLY / PIVOT / UNPIVOT WHERE GROUP BY WITH CUBE / WITH ROLLUP HAVING ORDER BY OFFSET-FETCH
논리 질의 처리 주문, 또는 바인딩 주문, 그것은 쿼리의 정확성을 정의, 개념 해석의 순서입니다. 한 단계에서 정의 된 객체가 후속 단계의 절에 제공 할 때의 순서를 결정한다.
----- Relational result 1. FROM 1.1. ON JOIN / APPLY / PIVOT / UNPIVOT 2. WHERE 3. GROUP BY 3.1. WITH CUBE / WITH ROLLUP 4. HAVING ---- After the HAVING step the Underlying Query Result is ready 5. SELECT 5.1. SELECT list 5.2. DISTINCT ----- Relational result ----- Non-relational result (a cursor) 6. ORDER BY 7. TOP / OFFSET-FETCH ----- Non-relational result (a cursor)
쿼리 프로세서가 FROM 절에 정의 (액세스) 테이블이나 뷰에 바인딩 할 수 있습니다 예를 들어, 이러한 개체 및 열 이후의 모든 단계를 사용할 수 있습니다.
반대로, SELECT 절 선행 모든 조항 SELECT 절에 정의 된 컬럼 alias 또는 유도 열을 참조 할 수있다. 그러나 이러한 열은 같은 ORDER BY 절로서 다음 절을 참조 할 수 있습니다.
관련된 윈도우 함수가 적용되기 전에 OVER 절은 행 세트의 분할 및 순서를 결정한다. 즉, OVER 절을 계산하여 그 결과 창에 대 기초 쿼리 결과 세트의 창 함수 내의 행 창 또는 사용자 지정 세트를 정의한다.
Msg 4108, Level 15, State 1, … Windowed functions can only appear in the SELECT or ORDER BY clauses.
이유는 뒤에 논리 질의 처리는 T-SQL에서 어떻게 작동 방식 때문이다. 논리 질의 처리는 SELECT 단계 5.1에 도달 할 경우에만 기본 쿼리 결과 때문에 설정된다. (즉,로부터 처리 후 GROUP BY 갖는 단계 임), 윈도우 함수는 질의의 절하여 SELECT 및 ORDER에서만 허용된다.
언급에 참고, 윈도우 함수는 여전히 심지어 관계형 모델은 주문 데이터를 처리하지 않는 관계형 층의 일부입니다. 선택 (SELECT) 5.1 단계 후의 결과. 모든 창 기능을 여전히 관계형이다.
또한, 엄밀히 말하면, 윈도우 함수는 WHERE 절에서 허용되지 않는 이유는 모호성을 만들 수 있지만 때문없는 논리 질의 처리는 T-SQL에서 SELECT 문을 처리하는 방법을 순서 때문이다.
링크 : 여기, 여기와 여기에
-
==============================
7.기본적으로 제 "WHERE"절의 조건 SQL 테이블로하지만 테이블 ROW_NUM = 1 보였다 동일한 열 / 값 ID로 판독 아직있다. 따라서이 작동하지 않습니다. 이유 그게 전부 우리는 먼저 괄호를 사용하고 그 후 우리는 WHERE 절을 작성합니다.
기본적으로 제 "WHERE"절의 조건 SQL 테이블로하지만 테이블 ROW_NUM = 1 보였다 동일한 열 / 값 ID로 판독 아직있다. 따라서이 작동하지 않습니다. 이유 그게 전부 우리는 먼저 괄호를 사용하고 그 후 우리는 WHERE 절을 작성합니다.
-
==============================
8.당신은 윈도우 기능을 수행 할 때 예 불행하게도 SQL은 술어가 합법적 인 사용자입니다 경우에도 화를 가져옵니다. 당신은 CTE를하거나 다음 CTE 참조하거나 나중에 값을 선택 중첩, 당신의 선택 문에서 값을 갖는 선택 중첩. 자기 설명해야합니다 간단한 예. 당신이 정말로 큰 데이터를하고 몇 가지 성능 문제에 대한 CTE의 미워하면 당신은 항상 임시 테이블이나 테이블 변수에 놓을 수 있습니다 설정합니다.
당신은 윈도우 기능을 수행 할 때 예 불행하게도 SQL은 술어가 합법적 인 사용자입니다 경우에도 화를 가져옵니다. 당신은 CTE를하거나 다음 CTE 참조하거나 나중에 값을 선택 중첩, 당신의 선택 문에서 값을 갖는 선택 중첩. 자기 설명해야합니다 간단한 예. 당신이 정말로 큰 데이터를하고 몇 가지 성능 문제에 대한 CTE의 미워하면 당신은 항상 임시 테이블이나 테이블 변수에 놓을 수 있습니다 설정합니다.
declare @Person table ( PersonID int identity, PersonName varchar(8)); insert into @Person values ('Brett'),('John'); declare @Orders table ( OrderID int identity, PersonID int, OrderName varchar(8)); insert into @Orders values (1, 'Hat'),(1,'Shirt'),(1, 'Shoes'),(2,'Shirt'),(2, 'Shoes'); --Select -- p.PersonName --, o.OrderName --, row_number() over(partition by o.PersonID order by o.OrderID) --from @Person p -- join @Orders o on p.PersonID = o.PersonID --where row_number() over(partition by o.PersonID order by o.orderID) = 2 -- yields: --Msg 4108, Level 15, State 1, Line 15 --Windowed functions can only appear in the SELECT or ORDER BY clauses. ; with a as ( Select p.PersonName , o.OrderName , row_number() over(partition by o.PersonID order by o.OrderID) as rnk from @Person p join @Orders o on p.PersonID = o.PersonID ) select * from a where rnk >= 2 -- only orders after the first one.
from https://stackoverflow.com/questions/13997177/why-no-windowed-functions-in-where-clauses by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] SQL (ORACLE) : ORDER BY와 LIMIT [중복] (0) | 2020.04.04 |
---|---|
[SQL] SQL 서버 - 선언 된 변수 절에 [중복] (0) | 2020.04.04 |
[SQL] 왜 널은 널 false로 동일하지 않다 (0) | 2020.04.04 |
[SQL] 열에 피벗 행 집계하지 않고 (0) | 2020.04.04 |
[SQL] SQL 서버 : 컬럼 트랜스 행 (0) | 2020.04.04 |