복붙노트

[SQL] 파티션 기능 COUNT () OVER 가능 DISTINCT 사용

SQL

파티션 기능 COUNT () OVER 가능 DISTINCT 사용

그래서 같이 독특한 NUMUSERS의 누적 합계를 얻기 위해 다음 사항을 작성하려고 해요 :

NumUsers = COUNT(DISTINCT [UserAccountKey]) OVER (PARTITION BY [Mth])

관리 스튜디오는 이것에 대해 너무 행복하지 않는 것 같습니다. 나는 DISTINCT 키워드를 제거 할 수 있지만 다음은 고유 한 카운트되지 않습니다 때 오류가 사라집니다.

DISTINCT 파티션 기능 내에서 가능한 것으로 표시되지 않습니다. 어떻게 고유 한 카운트를 찾아 가야합니까? 나는 그런 상관 하위 쿼리와 같은 전통적인 방법을 사용하십니까?

이것을으로 보는 것은 어쩌면 이러한 OVER 기능들이 실행 합계를 계산하기 위해 SQL-서버에서 사용할 수 없습니다하는 방식에 오라클 다르게 작동, 더 비트.

내가 누적 합계를 계산하기 위해 파티션 기능을 사용하려고 어디 SQLfiddle 여기에 라이브 예를 추가했습니다.

해결법

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

    1.DENSE_RANK를 사용하여 매우 간단한 해결책) (이

    DENSE_RANK를 사용하여 매우 간단한 해결책) (이

    dense_rank() over (partition by [Mth] order by [UserAccountKey]) 
    + dense_rank() over (partition by [Mth] order by [UserAccountKey] desc) 
    - 1
    

    매달 내에서 별개의 UserAccountKeys 수 : 이것은 당신이 요구 한 정확히 무엇을 줄 것이다.

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

    2.Necromancing :

    Necromancing :

    그것은 DENSE_RANK를 통해 MAX에 의해 카운트 DISTINCT를 통해 파티션을 모방 비교적 간단합니다 :

    ;WITH baseTable AS
    (
        SELECT 'RM1' AS RM, 'ADR1' AS ADR
        UNION ALL SELECT 'RM1' AS RM, 'ADR1' AS ADR
        UNION ALL SELECT 'RM2' AS RM, 'ADR1' AS ADR
        UNION ALL SELECT 'RM2' AS RM, 'ADR2' AS ADR
        UNION ALL SELECT 'RM2' AS RM, 'ADR2' AS ADR
        UNION ALL SELECT 'RM2' AS RM, 'ADR3' AS ADR
        UNION ALL SELECT 'RM3' AS RM, 'ADR1' AS ADR
        UNION ALL SELECT 'RM2' AS RM, 'ADR1' AS ADR
        UNION ALL SELECT 'RM3' AS RM, 'ADR1' AS ADR
        UNION ALL SELECT 'RM3' AS RM, 'ADR2' AS ADR
    )
    ,CTE AS
    (
        SELECT RM, ADR, DENSE_RANK() OVER(PARTITION BY RM ORDER BY ADR) AS dr 
        FROM baseTable
    )
    SELECT
         RM
        ,ADR
    
        ,COUNT(CTE.ADR) OVER (PARTITION BY CTE.RM ORDER BY ADR) AS cnt1 
        ,COUNT(CTE.ADR) OVER (PARTITION BY CTE.RM) AS cnt2 
        -- Not supported
        --,COUNT(DISTINCT CTE.ADR) OVER (PARTITION BY CTE.RM ORDER BY CTE.ADR) AS cntDist
        ,MAX(CTE.dr) OVER (PARTITION BY CTE.RM ORDER BY CTE.RM) AS cntDistEmu 
    FROM CTE
    

    노트 : 이 문제의 필드는 nullable이 아닌 필드를 가정합니다. 필드에서 하나 이상의 NULL-항목이 있다면, 당신은 일을 뺄 필요가있다.

  3. ==============================

    3.나는 SQL-서버 2008R2에서이 일을하는 유일한 방법은 상관 하위 쿼리를 사용하는 것입니다 생각, 또는 외부 적용 :

    나는 SQL-서버 2008R2에서이 일을하는 유일한 방법은 상관 하위 쿼리를 사용하는 것입니다 생각, 또는 외부 적용 :

    SELECT  datekey,
            COALESCE(RunningTotal, 0) AS RunningTotal,
            COALESCE(RunningCount, 0) AS RunningCount,
            COALESCE(RunningDistinctCount, 0) AS RunningDistinctCount
    FROM    document
            OUTER APPLY
            (   SELECT  SUM(Amount) AS RunningTotal,
                        COUNT(1) AS RunningCount,
                        COUNT(DISTINCT d2.dateKey) AS RunningDistinctCount
                FROM    Document d2
                WHERE   d2.DateKey <= document.DateKey
            ) rt;
    

    이것은 당신이 제시 한 구문을 사용하여 SQL-서버 2012에서 수행 할 수 있습니다 :

    SELECT  datekey,
            SUM(Amount) OVER(ORDER BY DateKey) AS RunningTotal
    FROM    document
    

    그러나, DISTINCT의 사용은 여전히 ​​허용되지 않습니다 그래서 DISTINCT 경우는 필요 및 / 또는 업그레이드가 다음 옵션이 아닌 경우 내가 OUTER가 당신의 최선의 선택입니다 적용 생각

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

    4.나는 일부 행은 계산에서 제외 할 필요가있는 경우 위의 다윗의 것과 유사하지만, 추가 트위스트와 함께 솔루션을 사용합니다. 이것은 [UserAccountKey]가 널 결코 것으로 가정합니다.

    나는 일부 행은 계산에서 제외 할 필요가있는 경우 위의 다윗의 것과 유사하지만, 추가 트위스트와 함께 솔루션을 사용합니다. 이것은 [UserAccountKey]가 널 결코 것으로 가정합니다.

    -- subtract an extra 1 if null was ranked within the partition,
    -- which only happens if there were rows where [Include] <> 'Y'
    dense_rank() over (
      partition by [Mth] 
      order by case when [Include] = 'Y' then [UserAccountKey] else null end asc
    ) 
    + dense_rank() over (
      partition by [Mth] 
      order by case when [Include] = 'Y' then [UserAccountKey] else null end desc
    )
    - max(case when [Include] = 'Y' then 0 else 1 end) over (partition by [Mth])
    - 1
    

    확장 된 예를 가진 SQL 바이올린은 여기에서 찾을 수 있습니다.

  5. from https://stackoverflow.com/questions/11202878/partition-function-count-over-possible-using-distinct by cc-by-sa and MIT license