SELECT 문에서 "이전 행" 값에 액세스할 수 있는 방법이 있습니까?
표의 두 줄 사이의 열 차이를 계산해야 합니다.이것을 SQL에서 직접 할 수 있는 방법이 있습니까?Microsoft SQL Server 2008을 사용하고 있습니다.
저는 다음과 같은 것을 찾고 있습니다.
SELECT value - (previous.value) FROM table
이전 변수가 마지막으로 선택한 행을 참조한다고 가정합니다.물론 그런 선택을 하면 n개의 행이 있는 테이블에서 n개의 행을 선택하게 됩니다. 이것은 아마 제가 필요로 하는 것이 아닐 것입니다.
그것이 어떤 식으로든 가능합니까?
지연 함수 사용:
SELECT value - lag(value) OVER (ORDER BY Id) FROM table
ID에 사용되는 시퀀스는 값을 건너뛸 수 있으므로 ID-1이 항상 작동하지는 않습니다.
SQL에는 기본적인 순서 개념이 없기 때문에 의미 있는 순서를 지정하려면 몇 개의 열로 순서를 지정해야 합니다.이와 같은 것:
select t1.value - t2.value from table t1, table t2
where t1.primaryKey = t2.primaryKey - 1
만약 당신이 물건을 주문하는 방법은 알고 있지만 현재 값(예: 알파벳 순으로 주문)을 얻는 방법은 모른다면, 표준 SQL에서는 그렇게 하는 방법을 모르지만, 대부분의 SQL 구현체에는 그것을 할 수 있는 확장이 있을 것입니다.
각 행이 구별되도록 행을 정렬할 수 있는 경우 SQL 서버를 사용할 수 있는 방법은 다음과 같습니다.
select rank() OVER (ORDER BY id) as 'Rank', value into temp1 from t
select t1.value - t2.value from temp1 t1, temp1 t2
where t1.Rank = t2.Rank - 1
drop table temp1
연결을 끊어야 하는 경우 ORDER BY에 필요한 만큼 열을 추가할 수 있습니다.
WITH CTE AS (
SELECT
rownum = ROW_NUMBER() OVER (ORDER BY columns_to_order_by),
value
FROM table
)
SELECT
curr.value - prev.value
FROM CTE cur
INNER JOIN CTE prev on prev.rownum = cur.rownum - 1
Oracle, PostgreSQL, SQL Server 및 기타 여러 RDBMS 엔진에는 다음과 같은 분석 기능이 있습니다.LAG그리고.LEAD바로 이런 일을 하는 것.
2012년 이전의 SQL Server에서는 다음 작업을 수행해야 합니다.
SELECT value - (
SELECT TOP 1 value
FROM mytable m2
WHERE m2.col1 < m1.col1 OR (m2.col1 = m1.col1 AND m2.pk < m1.pk)
ORDER BY
col1, pk
)
FROM mytable m1
ORDER BY
col1, pk
,어디에COL1주문 기준 열입니다.
인덱스 있음(COL1, PK)이 쿼리를 크게 향상시킵니다.
LEFT 조인은 조인 조건을 해결하여 테이블의 조인된 버전에서 일치하는 행이 "이전"에 대한 특정 정의를 위해 한 행 앞에 오도록 합니다.
업데이트: 처음에는 모든 행을 유지하고 이전 행이 없는 조건에 NULL을 사용할 것으로 생각했습니다.다시 읽어보면 행을 잘라내고 싶으므로 왼쪽 조인보다는 안쪽 조인을 해야 합니다.
업데이트:
최신 버전의 SQL Server에도 LAG 및 LED 윈도우 설정 기능을 사용할 수 있습니다.
select t2.col from (
select col,MAX(ID) id from
(
select ROW_NUMBER() over(PARTITION by col order by col) id ,col from testtab t1) as t1
group by col) as t2
선택한 답변은 시퀀스에 공백이 없는 경우에만 작동합니다.그러나 자동 생성된 ID를 사용하는 경우 롤백된 삽입으로 인해 시퀀스에 공백이 있을 수 있습니다.
공백이 있는 경우 이 방법이 작동해야 합니다.
declare @temp (value int, primaryKey int, tempid int identity)
insert value, primarykey from mytable order by primarykey
select t1.value - t2.value from @temp t1
join @temp t2
on t1.tempid = t2.tempid - 1
SQL 쿼리에서 이전 행을 참조하는 또 다른 방법은 CTE(재귀적 공통 테이블 표현식)를 사용하는 것입니다.
CREATE TABLE t (counter INTEGER);
INSERT INTO t VALUES (1),(2),(3),(4),(5);
WITH cte(counter, previous, difference) AS (
-- Anchor query
SELECT MIN(counter), 0, MIN(counter)
FROM t
UNION ALL
-- Recursive query
SELECT t.counter, cte.counter, t.counter - cte.counter
FROM t JOIN cte ON cte.counter = t.counter - 1
)
SELECT counter, previous, difference
FROM cte
ORDER BY counter;
결과:
| 계산대 | 이전의 | 차이 |
|---|---|---|
| 1 | 0 | 1 |
| 2 | 1 | 1 |
| 3 | 2 | 1 |
| 4 | 3 | 1 |
| 5 | 4 | 1 |
의 첫 합니다.cte에를 설정하는 곳에cte.counter을 싣다t.counter의 첫 t,cte.previous0까지, 그리고cte.difference에의 첫 t.counter.
의 각 합니다.cte의 t에서 재쿼 .cte.counter에대한을 t.counter의 각 t,cte.previous에대한을 cte.counter에의 cte,그리고.t.counter - cte.counter이 두 열 사이의 차이를 나타냅니다.
재귀 CTE는 행이 이전 행의 임의 결과를 참조할 수 있기 때문에 LAG 및 LED 기능보다 더 유연합니다. (재귀 함수 또는 프로세스는 프로세스의 입력이 상수인 첫 번째 입력을 제외하고 해당 프로세스의 이전 반복의 출력인 경우입니다.)
SQLite Online에서 이 쿼리를 테스트했습니다.
다음 함수를 사용하여 현재 행 값과 이전 행 값을 가져올 수 있습니다.
SELECT value,
min(value) over (order by id rows between 1 preceding and 1
preceding) as value_prev
FROM table
그러면 선택할 수 있습니다.value - value_prev.
언급URL : https://stackoverflow.com/questions/710212/is-there-a-way-to-access-the-previous-row-value-in-a-select-statement
'programing' 카테고리의 다른 글
| 모든 SQL Server 외부 키에 일치하는 인덱스가 있어야 합니까? (0) | 2023.05.04 |
|---|---|
| VBA 단일 시트를 CSV로 저장(전체 워크북이 아님) (0) | 2023.05.04 |
| 하위 모듈을 최신 커밋으로 업데이트 (0) | 2023.05.04 |
| 32비트 전용 Microsoft Common Controls(ListView)를 대체할 방법을 찾고 있습니다. (0) | 2023.05.04 |
| 여러 비동기 작업을 실행하고 모든 작업이 완료될 때까지 대기 (0) | 2023.05.04 |