조건부 선도/지연 기능 Postgres?
많은 사용자가 Postgres에서 윈도우 기능을 사용하여 조건부 선도/지연 기능을 구현하는 방법에 대해 당황해합니다. 이 예에는 다음과 같은 데이터가 포함된 테이블이 있습니다.
Name | Activity | Time |
---|---|---|
user1 | A1 | 12:00 |
user1 | E3 | 12:01 |
user1 | A2 | 12:02 |
user2 | A1 | 10:05 |
user2 | A2 | 10:06 |
user2 | A3 | 10:07 |
user2 | M6 | 10:07 |
user2 | B1 | 10:08 |
user3 | A1 | 14:15 |
user3 | B2 | 14:20 |
user3 | D1 | 14:25 |
user3 | D2 | 14:30 |
이 테이블을 이전 활동이 유형 A였던 각 사용자에 대해 유형 B의 다음 활동을 표시하는 보고서로 변환하려고 합니다. 구체적으로 다음과 같은 테이블을 만드는 것을 목표로 합니다.
Name | Activity | Next Activity |
---|---|---|
user1 | A2 | NULL |
user2 | A3 | B1 |
user3 | A1 | B2 |
조건부 창 함수
전통적으로 사용자는 이 문제를 해결하기 위해 Lead() 함수를 사용하려고 시도할 수 있습니다. 그러나 Postgres의 창 기능 제한으로 인해 조건부 기능은 직접 지원되지 않습니다. 특히, Lead()나 lag()에는 FILTER 절을 적용할 수 없습니다.
문제 해결
이 문제를 해결하려면 FILTER 절을 사용한다는 개념을 버려야 합니다. 조건부 리드 기능을 사용하고 대신 더 복잡한 쿼리 전략을 사용합니다. 한 가지 접근 방식은 DISTINCT ON 및 CASE 문을 사용하여 원하는 결과를 얻는 것입니다. 다음은 이 전략을 보여주는 쿼리입니다.
SELECT name , CASE WHEN a2 LIKE 'B%' THEN a1 ELSE a2 END AS activity , CASE WHEN a2 LIKE 'B%' THEN a2 END AS next_activity FROM ( SELECT DISTINCT ON (name) name , lead(activity) OVER (PARTITION BY name ORDER BY time DESC) AS a1 , activity AS a2 FROM t WHERE (activity LIKE 'A%' OR activity LIKE 'B%') ORDER BY name, time DESC ) sub;
설명
성능 고려 사항
소규모 데이터 세트의 경우 위 쿼리는 충분히 잘 수행되어야 합니다. 그러나 대규모 데이터세트의 경우 인덱싱이나 윈도우 기능과 같은 기술을 사용하여 쿼리를 최적화해야 할 수도 있습니다.
위 내용은 PostgreSQL에서 조건부 선도/지연 기능을 구현하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!