[SQL] 윈도우 기능 : LAST_VALUE (BY ... ASC ORDER) LAST_VALUE과 동일 (ORDER BY ... DESC)
SQL윈도우 기능 : LAST_VALUE (BY ... ASC ORDER) LAST_VALUE과 동일 (ORDER BY ... DESC)
샘플 데이터
CREATE TABLE test
(id integer, session_ID integer, value integer)
;
INSERT INTO test
(id, session_ID, value)
VALUES
(0, 2, 100),
(1, 2, 120),
(2, 2, 140),
(3, 1, 900),
(4, 1, 800),
(5, 1, 500)
;
현재 쿼리
select
id,
last_value(value) over (partition by session_ID order by id) as last_value_window,
last_value(value) over (partition by session_ID order by id desc) as last_value_window_desc
from test
ORDER BY id
나는 LAST_VALUE () 윈도우 기능에 문제로 실행되었다 : http://sqlfiddle.com/#!15/bcec0/2
바이올린에서 나는 LAST_VALUE () 쿼리 내에서 정렬 방향으로 해결하려고 노력하고있다.
편집하다: 문제는되지 않습니다 : 나는 모든 시간 마지막 값 방법과 프레임 절을 사용하는 방법 (무제한의 이전 및 억제 할 다음)를하지 않는 이유는. 나는 FIRST_VALUE (내림차순) 및 LAST_VALUE () 및 LAST_VALUE ()는 당신에게 모든 시간 마지막 값을 제공하지 않는 문제의 차이에 대해 알고 :
기본 프레임 절은 현재 행까지 위의 제한은 없습니다. 그래서 첫 번째 값은 항상 절을 withing에 첫 번째 행을주고있다. 단지 하나의 행이있는 경우는 문제가되지 않습니다 그래서 또는 1 hundered가 (프레임 절은 모두 백 포함) (프레임 절은이 하나를 포함). 결과는 항상 첫 번째입니다. DESC 순서는 동일합니다 : DESC 정렬 순서를 변경 한 후 첫 번째 행은 마지막 값, 당신은 얼마나 많은 행이없는 문제입니다.
LAST_VALUE으로 () 동작은 매우 유사하다 :이 한 행 : 당신은 하나 개의 행이있는 경우, 그것은 당신에게 기본 프레임 조항의 마지막 값을 제공합니다. 두번째 행에서, 프레임 절 마지막 번째이며, 두 개의 행을 포함한다. () LAST_VALUE는 현재 행까지 모든 행의 마지막 행을하지만 마지막 행을 포기하지 않는 이유입니다.
내가 DESC I에 순서를 변경하지만 내가 첫 번째 행에서이 하나를 얻을 수 있도록 내가 두 번째 행 등에서 마지막으로 두 번째보다, 우선 마지막 행을 가지고 기대하고있다. 하지만 그 결과가 아니다. 왜?
현재 예를 들어이는 FIRST_VALUE (), FIRST_VALUE (내림차순)) (LAST_VALUE, LAST_VALUE (내림차순)과 내가이 LAST_VALUE (내림차순)에 대한 기대 오전에 대한 결과는 다음과 같습니다
id | fv_asc | fv_desc | lv_asc | lv_desc | lv_desc(expecting)
----+--------+---------+--------+---------+--------------------
0 | 100 | 140 | 100 | 100 | 140
1 | 100 | 140 | 120 | 120 | 120
2 | 100 | 140 | 140 | 140 | 100
3 | 900 | 500 | 900 | 900 | 500
4 | 900 | 500 | 800 | 800 | 800
5 | 900 | 500 | 500 | 500 | 900
나에게는 DESC 플래그 BY 순서는 기본 프레임 절 LAST_VALUE () 호출 내에서 무시됩니다 것으로 보인다. 하지만 그것은 FIRST_VALUE () 호출 내에 있지 않습니다. 내 질문은 그래서 왜이 LAST_VALUE이다 ()는 LAST_VALUE (내림차순)과 같은 결과?
해결법
-
==============================
1.LAST_VALUE ()의 문제는 절을 윈도의 기본 규칙은 당신이 정말로 원하는 값을 제거하는 것입니다. 이것은 매우 미묘한 문제이며이 기능을 지원하는 모든 데이터베이스의 사실이다.
LAST_VALUE ()의 문제는 절을 윈도의 기본 규칙은 당신이 정말로 원하는 값을 제거하는 것입니다. 이것은 매우 미묘한 문제이며이 기능을 지원하는 모든 데이터베이스의 사실이다.
이것은 오라클 블로그에서 온다 :
따라서, 단지 FIRST_VALUE ()를 사용합니다. 이것은 당신이 원하는 것을 :
with test (id, session_ID, value) as ( (VALUES (0, 2, 100), (1, 2, 120), (2, 2, 140), (3, 1, 900), (4, 1, 800), (5, 1, 500) ) ) select id, first_value(value) over (partition by session_ID order by id) as first_value_window, first_value(value) over (partition by session_ID order by id desc) as first_value_window_desc from test order by id
-
==============================
2.1 년 후에 나는 해결책을 가지고있다 :
1 년 후에 나는 해결책을 가지고있다 :
이 문장을 가지고 :
SELECT id, array_accum(value) over (partition BY session_ID ORDER BY id) AS window_asc, first_value(value) over (partition BY session_ID ORDER BY id) AS first_value_window_asc, last_value(value) over (partition BY session_ID ORDER BY id) AS last_value_window_asc, array_accum(value) over (partition BY session_ID ORDER BY id DESC) AS window_desc, first_value(value) over (partition BY session_ID ORDER BY id DESC) AS first_value_window_desc, last_value(value) over (partition BY session_ID ORDER BY id DESC) AS last_value_window_desc FROM test ORDER BY id
이것은 제공
id window_asc first_value_window_asc last_value_window_asc window_desc first_value_window_desc last_value_window_desc -- ------------- ---------------------- --------------------- ------------- ----------------------- ---------------------- 0 {100} 100 100 {140,120,100} 140 100 1 {100,120} 100 120 {140,120} 140 120 2 {100,120,140} 100 140 {140} 140 140 3 {900} 900 900 {500,800,900} 500 900 4 {900,800} 900 800 {500,800} 500 800 5 {900,800,500} 900 500 {500} 500 500
array_accum는 사용 된 창을 보여줍니다. 첫 번째와 윈도우의 현재 마지막 값을가 볼 수 있습니다.
쇼에게 실행 계획을 무슨 일이 있었는지 :
"Sort (cost=444.23..449.08 rows=1940 width=12)" " Sort Key: id" " -> WindowAgg (cost=289.78..338.28 rows=1940 width=12)" " -> Sort (cost=289.78..294.63 rows=1940 width=12)" " Sort Key: session_id, id" " -> WindowAgg (cost=135.34..183.84 rows=1940 width=12)" " -> Sort (cost=135.34..140.19 rows=1940 width=12)" " Sort Key: session_id, id" " -> Seq Scan on test (cost=0.00..29.40 rows=1940 width=12)"
당신이 볼 수 있습니다 : 첫 번째는 처음 세 개의 창 기능을위한 ID에 의해 순서가있다.
이것은 제공 (질문에 명시된 바와 같이)
id window_asc first_value_window_asc last_value_window_asc -- ------------- ---------------------- --------------------- 3 {900} 900 900 4 {900,800} 900 800 5 {900,800,500} 900 500 0 {100} 100 100 1 {100,120} 100 120 2 {100,120,140} 100 140
다음 세 가지 윈도우 기능의 ID DESC BY ORDER : 그럼 당신은 다른 종류를 볼 수 있습니다. 이런 종류의 수 있습니다 :
id window_asc first_value_window_asc last_value_window_asc -- ------------- ---------------------- --------------------- 5 {900,800,500} 900 500 4 {900,800} 900 800 3 {900} 900 900 2 {100,120,140} 100 140 1 {100,120} 100 120 0 {100} 100 100
이것은 DESC 창 기능을 정렬로 실행됩니다. array_accum 열 쇼 결과 창 :
id window_desc -- ------------- 5 {500} 4 {500,800} 3 {500,800,900} 2 {140} 1 {140,120} 0 {140,120,100}
얻어진 (FIRST_VALUE 및 DESC) LAST_VALUE DESC 이제 LAST_VALUE ASC 절대적으로 동일하다 :
id window_asc last_value_window_asc window_desc last_value_window_desc -- ------------- --------------------- ------------- ---------------------- 5 {900,800,500} 500 {500} 500 4 {900,800} 800 {500,800} 800 3 {900} 900 {500,800,900} 900 2 {100,120,140} 140 {140} 140 1 {100,120} 120 {140,120} 120 0 {100} 100 {140,120,100} 100
LAST_VALUE ASC는 LAST_VALUE DESC 동일 왜 지금은 나에게 분명 해졌다. 이는 윈도우 함수의 두 번째 순서는 거꾸로 창을 제공하기 때문이다.
(문장의 마지막 주문 BY IST 실행 계획의 마지막 종류.)
이 쿼리 쇼 약간의 최적화 가능성 : 약간의 보너스로 먼저 다음 ASC의 사람을 DESC 창을 호출하는 경우에는 세 번째 종류의 필요가 없습니다. 그것은이 순간에 적절한 종류입니다.
-
==============================
3.윈도우 프레임이 어떻게 정의되는지 확인합니다. 이 예는 도움이 될 수 있습니다 :
윈도우 프레임이 어떻게 정의되는지 확인합니다. 이 예는 도움이 될 수 있습니다 :
select id, last_value(value) over ( partition by session_id order by id ) as lv_asc, last_value(value) over ( partition by session_id order by id desc ) as lv_desc, last_value(value) over ( partition by session_id order by id rows between unbounded preceding and unbounded following ) as lv_asc_unbounded, last_value(value) over ( partition by session_id order by id desc rows between unbounded preceding and unbounded following ) as lv_desc_unbounded from t order by id; id | lv_asc | lv_desc | lv_asc_unbounded | lv_desc_unbounded ----+--------+---------+------------------+------------------- 0 | 100 | 100 | 140 | 100 1 | 120 | 120 | 140 | 100 2 | 140 | 140 | 140 | 100 3 | 900 | 900 | 500 | 900 4 | 800 | 800 | 500 | 900 5 | 500 | 500 | 500 | 900
from https://stackoverflow.com/questions/42299101/window-functions-last-valueorder-by-asc-same-as-last-valueorder-by-d by cc-by-sa and MIT license
'SQL' 카테고리의 다른 글
[SQL] 절에 가변적 목록과 테이블에서 SELECT (0) | 2020.05.15 |
---|---|
[SQL] SQL : 특정 열 ... 가능한 내에서 문자열을 사용하여 ORDER? (0) | 2020.05.15 |
[SQL] 방법으로 숫자를 포맷하는 방법 "을 참조하십시오." 1000 개 단위 구분하고 ","같은 소수 구분 기호로? (0) | 2020.05.15 |
[SQL] 왜이 반환 자원 ID # 2를합니까? [복제] (0) | 2020.05.15 |
[SQL] 액세스 2010 : 쿼리 식의 구문 오류 (누락 된 연산자) (0) | 2020.05.15 |