복붙노트

[SQL] CROSS에 포스트 그레스 아날로그는 SQL 서버에 적용

SQL

CROSS에 포스트 그레스 아날로그는 SQL 서버에 적용

나는 포스트 그레스 9.1 MS SQL 서버 2005 용으로 작성된 마이그레이션 SQL 쿼리에 필요합니다. CROSS이 쿼리에 적용을 대체하는 가장 좋은 방법은 무엇입니까?

SELECT *
FROM V_CitizenVersions         
CROSS APPLY     
       dbo.GetCitizenRecModified(Citizen, LastName, FirstName, MiddleName,
BirthYear, BirthMonth, BirthDay, ..... ) -- lots of params

GetCitizenRecModified () 함수는 테이블 반환 함수입니다. 그것은, 그것은 어떤 어려운 계산을 정말 엄청난 수 있고 난 그것을 포기할 수 없기 때문에 나는이 기능의 코드를 배치 할 수 없습니다.

해결법

  1. ==============================

    1.포스트 그레스 9.3 이상에서는 것은 조인 측면 사용

    포스트 그레스 9.3 이상에서는 것은 조인 측면 사용

    SELECT v.col_a, v.col_b, f.*  -- no parentheses here, f is a table alias
    FROM   v_citizenversions v
    LEFT   JOIN LATERAL f_citizen_rec_modified(v.col1, v.col2) f ON true
    WHERE  f.col_c = _col_c;
    

    왜 왼쪽 측면 가입 ... 사실 ON?

    이전 버전의 경우, 당신이 집합을 반환하는 기능을하려고 생각 (RETURNS 표 또는 RETURNS가 기록 또는 RETURNS 기록을 SETOF) 무엇을 달성 할 수있는 아주 간단한 방법이있다 :

    SELECT *, (f_citizen_rec_modified(col1, col2)).*
    FROM   v_citizenversions v
    

    이 기능은 외부 쿼리의 각 행에 대한 값을 계산 한 번. 함수가 여러 행을 반환하는 경우, 결과 행이 따라 곱한다. 모든 괄호는 구문 행 유형을 분해해야합니다. 테이블 함수는 다음과 같다 :

    CREATE OR REPLACE FUNCTION f_citizen_rec_modified(_col1 int, _col2 text)
      RETURNS TABLE(col_c integer, col_d text) AS
    $func$
    SELECT s.col_c, s.col_d
    FROM   some_tbl s
    WHERE  s.col_a = $1
    AND    s.col_b = $2
    $func$ LANGUAGE sql;
    

    당신이 열이 같은 수준에 표시되지 않기 때문에 WHERE 절을 적용 할 경우 하위 쿼리 또는 CTE이 포장해야합니다. (이 함수의 모든 출력 열에 대한 평가를 반복 방지하기 때문에 그리고 그것은, 어쨌든 성능을 위해 더 나은)

    SELECT col_a, col_b, (f_row).*
    FROM (
       SELECT col_a, col_b, f_citizen_rec_modified(col1, col2) AS f_row
       FROM   v_citizenversions v
       ) x
    WHERE (f_row).col_c = _col_c;
    

    이 식물 또는 유사한 무언가를 할 수있는 여러 가지 다른 방법이 있습니다. 그것은 모두 당신이 정확하게 원하는에 따라 달라집니다.

  2. ==============================

    2.Necromancing : PostgreSQL의 9.3의 새로운 기능 :

    Necromancing : PostgreSQL의 9.3의 새로운 기능 :

    측면 키워드

    왼쪽 | 바로 | 내측은 외측 JOIN

    INNER는 측면 크로스가 적용되는 동일 가입 그리고 왼쪽 측면은 외부 적용과 동일 가입

    사용 예제 :

    SELECT * FROM T_Contacts 
    
    --LEFT JOIN T_MAP_Contacts_Ref_OrganisationalUnit ON MAP_CTCOU_CT_UID = T_Contacts.CT_UID AND MAP_CTCOU_SoftDeleteStatus = 1 
    --WHERE T_MAP_Contacts_Ref_OrganisationalUnit.MAP_CTCOU_UID IS NULL -- 989
    
    
    LEFT JOIN LATERAL 
    (
        SELECT 
             --MAP_CTCOU_UID    
             MAP_CTCOU_CT_UID   
            ,MAP_CTCOU_COU_UID  
            ,MAP_CTCOU_DateFrom 
            ,MAP_CTCOU_DateTo   
       FROM T_MAP_Contacts_Ref_OrganisationalUnit 
       WHERE MAP_CTCOU_SoftDeleteStatus = 1 
       AND MAP_CTCOU_CT_UID = T_Contacts.CT_UID 
    
        /*  
        AND 
        ( 
            (__in_DateFrom <= T_MAP_Contacts_Ref_OrganisationalUnit.MAP_KTKOE_DateTo) 
            AND 
            (__in_DateTo >= T_MAP_Contacts_Ref_OrganisationalUnit.MAP_KTKOE_DateFrom) 
        ) 
        */
       ORDER BY MAP_CTCOU_DateFrom 
       LIMIT 1 
    ) AS FirstOE 
    
  3. ==============================

    3.어윈 Brandstetter의 대답처럼 나는 그러나, 나는 성능 문제를 발견했습니다 : 실행할 때

    어윈 Brandstetter의 대답처럼 나는 그러나, 나는 성능 문제를 발견했습니다 : 실행할 때

    SELECT *, (f_citizen_rec_modified(col1, col2)).*
    FROM   v_citizenversions v
    

    f_citizen_rec_modified 함수 (v_citizenversions 모든 행 곱)이 리턴 모든 열에 대해 RAN 1 시간이 될 것이다. 나는이 효과에 대한 문서를 찾을 수 있지만, 디버깅하여 추론 할 수 있었다하지 않았다. 이제 문제는 우리가이 성능 로빙 부작용없이 (이전에 사용할 수있는 조인 측면 9.3)이 효과를 얻을 수있는 방법이된다?

    업데이트 : 나는 대답을 찾을 것으로 보인다. 다음과 같이 쿼리를 다시 작성 :

    select x.col1, x.col2, x.col3, (x.func).* 
    FROM (select SELECT v.col1, v.col2, v.col3, f_citizen_rec_modified(col1, col2) func
    FROM   v_citizenversions v) x
    

    주요 차이점 제 원시 함수 인 결과를 얻는 (내부 부질) 다음에 다른 컬럼에 검거에서 그에게 그 결과를 선택하도록 배치. 이 PG 9.2에서 테스트되었다

  4. ==============================

    4.이 링크는 9.0 포스트 그레스에서 작업을 수행하는 방법을 보여 나타납니다 :

    이 링크는 9.0 포스트 그레스에서 작업을 수행하는 방법을 보여 나타납니다 :

    PostgreSQL은 : 재귀 CTE를 매개 변수화

    섹션의 페이지 "Emulation 소프트웨어 CROSS이 설정을 돌려주는 기능을 적용"아래로 더합니다. 예 후 제한 목록을 참고하시기 바랍니다.

  5. from https://stackoverflow.com/questions/11472790/postgres-analogue-to-cross-apply-in-sql-server by cc-by-sa and MIT license