복붙노트

[SQL] BY 절 SQL GROUP에서 빈 그룹을 반환하는 방법

SQL

BY 절 SQL GROUP에서 빈 그룹을 반환하는 방법

나는, 계약 및 오프 계약 각 위치에서 소비되는 양을 반환하는 쿼리가 그 같은 반환 뭔가 :

Location     | ContractStatus | Expenses
-------------+----------------+---------
New York     | Ad-hoc         | 2043.47
New York     | Contracted     | 2894.57
Philadelphia | Ad-hoc         | 3922.53
Seattle      | Contracted     | 2522.00

문제는 내가 단지 모든 임시 또는 모든 계약 비용입니다 위치에 대한 하나 개의 행을 얻을 수있다. 나는 두 행은 다음과 같이 각 위치에 백업 좀하고 싶습니다 :

Location     | ContractStatus | Expenses
-------------+----------------+---------
New York     | Ad-hoc         | 2043.47
New York     | Contracted     | 2894.57
Philadelphia | Ad-hoc         | 3922.53
Philadelphia | Contracted     |    0.00
Seattle      | Ad-hoc         |    0.00
Seattle      | Contracted     | 2522.00

나는 SQL을 통해이 작업을 수행 할 수있는 방법이 있습니까? 여기에 내가 (2005 SQL 서버)를 사용하고있어 실제 쿼리는 다음과 같습니다

SELECT Location, 
     CASE WHEN Orders.Contract_ID IS NULL 
          THEN 'Ad-hoc' ELSE 'Contracted' END 
                     AS ContractStatus,
     SUM(OrderTotal) AS Expenses
FROM Orders
GROUP BY Location, 
    CASE WHEN Orders.Contract_ID IS NULL 
         THEN 'Ad-hoc' ELSE 'Contracted' END
ORDER BY Location ASC, ContractStatus ASC

해결법

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

    1.예, 단지 애드혹의 ordertotal를 반환 표현하고, 다른 사람에 대한 0, 반대를하지 다른 하나를 구성하고, 그 표현의 합계. 이 두 개의 열 애드혹 하나와 계약에 대한 하나의 위치 당 하나 개의 행을 포함합니다 ...

    예, 단지 애드혹의 ordertotal를 반환 표현하고, 다른 사람에 대한 0, 반대를하지 다른 하나를 구성하고, 그 표현의 합계. 이 두 개의 열 애드혹 하나와 계약에 대한 하나의 위치 당 하나 개의 행을 포함합니다 ...

     SELECT Location,  
         Sum(Case When Contract_ID Is Null Then OrderTotal Else 0 End) AdHoc,
         Sum(Case When Contract_ID Is Null Then 0 Else OrderTotal  End) Contracted
     FROM Orders 
     GROUP BY Location
    

    당신이 정말로 각각에 대해 별도의 행을 원하는 경우, 다음 한 가지 방법은하는 것입니다 :

     SELECT Location, Min('AdHoc') ContractStatus,
         Sum(Case When Contract_ID Is Null 
                  Then OrderTotal Else 0 End) OrderTotal
     FROM Orders 
     GROUP BY Location
     Union
     SELECT Location, Min('Contracted') ContractStatus,
         Sum(Case When Contract_ID Is Null 
                  Then 0 Else OrderTotal  End) OrderTotal
     FROM Orders 
     GROUP BY Location
     Order By Location
    
  2. ==============================

    2.먼저 별개의 위치와 계약의 목록을 채울 필요가있다. 나는 그것을 실행하지 않은대로 몇 가지 구문 오류가있을 수 있습니다,이 쿼리를 참조하십시오.

    먼저 별개의 위치와 계약의 목록을 채울 필요가있다. 나는 그것을 실행하지 않은대로 몇 가지 구문 오류가있을 수 있습니다,이 쿼리를 참조하십시오.

    ;WITH Locations AS 
    (
        SELECT DISTINCT Location, 1 as ContractStatus
        FROM    Orders 
        UNION 
        SELECT DISTINCT Location, 2 as ContractStatus
        FROM    Orders
    )
    
    SELECT  Location, 
            CASE 
                WHEN L.ContractStatus = 1 THEN 'Ad-hoc'
                ELSE 'Contracted'
            END, 
            ISNULL(SUM(OrderTotal),0) Expenses
    FROM    Locations L
        LEFT JOIN Orders O 
            ON L.Location = O.Location AND L.ContractStatus = CASE WHEN O.Contract_ID IS NULL THEN 1 ELSE 2 END
    GROUP BY    L.Location, 
                CASE 
                    WHEN L.ContractStatus = 1 THEN 'Ad-hoc'
                    ELSE 'Contracted'
                END 
    
  3. ==============================

    3.당신은 어떻게 든 그룹화하기 전에 각 위치에 대한 각 상태의 적어도 하나 개의 행을 작성해야합니다. 여기에 한 가지 방법이다 :

    당신은 어떻게 든 그룹화하기 전에 각 위치에 대한 각 상태의 적어도 하나 개의 행을 작성해야합니다. 여기에 한 가지 방법이다 :

    SELECT s.Location, s.ContractStatus, ISNULL(o.Expenses, 0) AS Expenses
    FROM
    (
        SELECT
            Location,
            CASE
                WHEN Contract_ID IS NULL THEN 'Ad-hoc'
                ELSE 'Contracted'
            END AS ContractStatus,
            SUM(OrderTotal) AS Expenses
        FROM Orders
        GROUP BY
            Location,
            CASE WHEN Contract_ID IS NULL THEN 'Ad-hoc' ELSE 'Contracted' END)
    ) o
    RIGHT JOIN
    (
        SELECT DISTINCT o.Location, s1.ContractStatus
        FROM Orders o
        CROSS JOIN
        (
            SELECT 'Ad-hoc' AS ContractStatus
            UNION ALL
            SELECT 'Contracted'
        ) s1
    ) s
    ON s.Location = o.Location
    AND s.ContractStatus = o.ContractStatus
    

    편집 : 그 DISTINCT / CROSS의 성능에 대해 확실하지 않다 콤보 가입하지만 한 번 또는 자주 사용하는 쿼리의 경우 확인을해야합니다.

  4. from https://stackoverflow.com/questions/1980678/how-to-return-empty-groups-in-sql-group-by-clause by cc-by-sa and MIT license