web-dev-qa-db-ja.com

クロス適用を使用しているときに、「空の」レコードを強制的に表示できますか?

一部のレコードを強制的に表示したいということを除いて、非常にうまく機能しているクエリがあります。私はSqlServer 2016を使用しており、このクエリは最終的にVIEWで使用され、SSRS 2016で使用されます。SSRSで目的の動作を実行できる場合、またはPIVOTなどに変更できる場合は、そのオプションを利用できます。

以下に示すサンプル画像を模倣するために、いくつかのDDLを下に配置します。

私が取得しているデータは以下のようになります:

enter image description here

そして、クロスアプライを使用して合計を垂直方向に表示します。

enter image description here

上記のように、stateおよびSUI_Stateが「IN」であるレコードは、SUI_Stateが「OH」であるという問題があります。これにより、「[IN]」のSUI_State1を持つレコードがないため、「IN」のSUIレコードが出力に含まれなくなります。

「IN Employee SUI」、「IN Employer SUI」などを値0で強制的に表示する方法はありますか?

State/SDI状態とSUI状態が異なる多くの状態があるため、ロジックをハードコードできません。

そして、ここに私の現在のクエリで同様のデータを調整したものがあります。この質問では値は重要ではありません。SUIレコードが「IN」の状態で表示されるように強制するだけです。

    CREATE TABLE #EmployeeTaxes
(    Payroll int
    ,SDI_State char(2)
    ,SUI_State char(2)
    ,State char(2)
    ,SIT DECIMAl(19,2)
    ,Employee_SDI DECIMAL(19,2)
    ,Employer_SDI DECIMAL(19,2)
    ,Employee_SUI DECIMAL(19,2)
    ,Employer_SUI DECIMAL(19,2)
)

--Data in source table
INSERT INTO #EmployeeTaxes
VALUES   (4, 'IN', 'OH', 'IN', 50, 0, 0, 0, 100)
        ,(4, 'IN', 'OH', 'IN', 50, 0, 0, 0, 100)
        ,(4, 'IN', 'OH', 'IN', 50, 0, 0, 0, 100)
        ,(4, 'IN', 'OH', 'IN', 50, 0, 0, 0, 100)
        ,(4, 'IN', 'OH', 'IN', 50, 0, 0, 0, 100)
        ,(4, 'OH', 'OH', 'OH', 50, 0, 0, 0, 100)
        ,(4, 'OH', 'OH', 'OH', 50, 0, 0, 0, 100)
        ,(4, 'OH', 'OH', 'OH', 50, 0, 0, 0, 100)
        ,(4, 'OH', 'OH', 'OH', 50, 0, 0, 0, 100)


--My Current Query
SELECT Payroll
      ,v.Item                       AS [Witholding]
      ,SUM(v.TaxValue)              AS Tax  
      ,v.OrderByNumber              AS [OrderByNumber]
FROM #EmployeeTaxes
CROSS APPLY (
    VALUES ([STATE]   + ' SIT', SIT, [STATE] + '110')
          ,(SDI_STATE + ' Employee SDI', EMPLOYEE_SDI,SDI_STATE + '111')
          ,(SDI_STATE + ' Employer SDI', EMPLOYER_SDI,SDI_STATE + '112')
          ,(SUI_STATE + ' Employee SUI', EMPLOYEE_SUI,SUI_STATE + '113')
          ,(SUI_STATE + ' Employer SUI', EMPLOYER_SUI,SUI_STATE + '114A')
          ,(SUI_STATE + ' Total', EMPLOYEE_SUI + EMPLOYER_SUI, SUI_State + '114B')
          ,(SDI_STATE + ' Total', EMPLOYEE_SDI + EMPLOYER_SDI , SDI_State + '114B')
          ,('---------------------------------',NULL,[STATE] + '121')

) v (Item, TaxValue, OrderByNumber)
GROUP BY Payroll, OrderByNumber, v.Item
ORDER BY PAYROLL, OrderByNumber 
DROP TABLE #EmployeeTaxes
4
Jeff.Clark

何をしているのかは少しわかりませんが、GROUP BYクエリに欠損値を追加する1つの方法は、集計列に0またはNULLを指定してすべての行を開始テーブルに追加することです。 @RDFozzが指摘したように、COUNT集計を行う場合はNULLを使用する必要があります。そうしないと、結果が膨らむためです。ただし、SUM集計のみを実行し、COALESCEに煩わされたくない場合は、0が適切な選択です。

これはUNION ALLで実現できます。 1つの実装は次のとおりです。

SELECT Payroll
      ,v.Item                       AS [Witholding]
      ,SUM(v.TaxValue)              AS Tax  
      ,v.OrderByNumber              AS [OrderByNumber]
FROM 
(
    SELECT * 
    FROM #EmployeeTaxes

    UNION ALL

    SELECT DISTINCT Payroll, [STATE], [STATE], [STATE], 0, 0, 0, 0, 0 
    FROM #EmployeeTaxes
) AS #EmployeeTaxes
CROSS APPLY (
    VALUES ([STATE]   + ' SIT', SIT, [STATE] + '110')
          ,(SDI_STATE + ' Employee SDI', EMPLOYEE_SDI,SDI_STATE + '111')
          ,(SDI_STATE + ' Employer SDI', EMPLOYER_SDI,SDI_STATE + '112')
          ,(SUI_STATE + ' Employee SUI', EMPLOYEE_SUI,SUI_STATE + '113')
          ,(SUI_STATE + ' Employer SUI', EMPLOYER_SUI,SUI_STATE + '114A')
          ,(SUI_STATE + ' Total', EMPLOYEE_SUI + EMPLOYER_SUI, SUI_State + '114B')
          ,(SDI_STATE + ' Total', EMPLOYEE_SDI + EMPLOYER_SDI , SDI_State + '114B')
          ,('---------------------------------',NULL,[STATE] + '121')

) v (Item, TaxValue, OrderByNumber)
GROUP BY Payroll, OrderByNumber, v.Item
ORDER BY PAYROLL, OrderByNumber;

これはあなたが望むものに近いと思いますか?上の結果セットは質問のクエリからのもので、下の結果セットは私のものです。

result sets

2
Joe Obbish