0

レポート ビルダーの SSRS で使用する一連のフィールドを統合するストアド プロシージャが SQL Server にあります。プロシージャは FileId を受け取り、そのロジックを実行します。File が Solicitor フィールドと Arresting Officer フィールドを検出または参照できなくなるまで、意図したとおりに機能します。

fileId に Arresting Officer または Solicitor が関連付けられていない場合でも結果を返すには、これが必要です。シンプルなものだと確信しています。基本的に、CTE がクエリから何も返さない場合でも、デフォルトの行が必要です。

 ALTER PROCEDURE [dbo].[GetRollCallData] 
    @Ids        VARCHAR(255),
    @LexiconId  INT,
    @UUID       UNIQUEIDENTIFIER,
    @ReadOnly   INT
 AS


 DECLARE @TableCode INT
 SET @TableCode = 58

 IF @Ids <> ''
    BEGIN
        EXEC InsertInSelectionCache @Ids, @UUID, @TableCode, 0
        IF @ReadOnly = 1
            WITH DOACTE AS(
            SELECT ROW_NUMBER() OVER(PARTITION BY [File].Id ORDER BY CustomRecordsetId DESC) AS RowNumber, [File].*, FileType2Lexicon.Label as FileTypeLabel, [People].DefaultPhone, [People].InvertedName, CustomField.Name as FieldLabel, CustomFieldValue.Value as FieldValue
                FROM FileType2Lexicon, SelectionCache, [People], [File]
                INNER JOIN [CustomRecordSet]
                ON [CustomRecordset].RecordId = [File].Id
                INNER JOIN CustomFieldValue
                ON  [CustomRecordset].Id = CustomFieldValue.CustomRecordsetId
                INNER JOIN [CustomField2Lexicon]
                ON CustomField2Lexicon.CustomFieldId = CustomFieldValue.CustomFieldId
                INNER JOIN [CustomField]
                ON CustomField.Id = CustomField2Lexicon.CustomFieldId
                WHERE   [File].Id = SelectionCache.RecordId
                AND SelectionCache.UUID = @UUID
                AND SelectionCache.TableCode = @TableCode -- this is the code for File table  
                AND     [File].Id <> 0 
                AND     [File].FileTypeId = FileType2Lexicon.FileTypeId 
                AND     FileType2Lexicon.LexiconId = @LexiconId
                AND     [File].ClientIdString = [People].ClientIdString
                AND     CustomFieldValue.Value <> ''),

            SolicitorCTE AS(

                SELECT [People].Name AS SolicitorName, [File].Id
                FROM SelectionCache, [File]
                INNER JOIN [People2File]
                ON [People2File].FileId = [File].Id
                INNER JOIN [Role2Lexicon]
                ON [Role2Lexicon].RoleId = [People2File].RoleId
                INNER JOIN [People]
                ON [People].Id = [People2File].PeopleId
                WHERE 
                [File].Id = SelectionCache.RecordId
                AND SelectionCache.UUID = @UUID
                AND SelectionCache.TableCode = @TableCode -- this is the code for File table  
                AND [File].Id <> 0
                AND [Role2Lexicon].Label = 'Solicitor'),

             ArrestingOfficerCTE AS(
                SELECT ROW_NUMBER() OVER(PARTITION BY [File].Id ORDER BY [People].InvertedName ASC) AS RowNumber, [People].Name AS ArrestingOfficerName, [People].CompanyName AS ArrestingOfficerCompany, [File].Id
                FROM SelectionCache, [File]
                INNER JOIN [People2File]
                ON [People2File].FileId = [File].Id
                INNER JOIN [Role2Lexicon]
                ON [Role2Lexicon].RoleId = [People2File].RoleId
                INNER JOIN [People]
                ON [People].Id = [People2File].PeopleId
                WHERE 
                [File].Id = SelectionCache.RecordId
                AND SelectionCache.UUID = @UUID
                AND SelectionCache.TableCode = @TableCode -- this is the code for File table  
                AND [File].Id <> 0
                AND [Role2Lexicon].Label = 'Arresting Officer'),

            PivotCTE AS(
                SELECT *
                FROM
                (Select Id, FieldLabel, FieldValue FROM DOACTE) AS Source
                PIVOT(
                MAX(FieldValue) FOR FieldLabel IN ([Date_Arrest], [Graphic_Client], [Ticket_1], [Ticket_2], [Ticket_3], [Ticket_4], [Ticket_5], [Charge_1], [Charge_2], [Charge_3], [Charge_4], [Charge_5])) as Pvt
                )

            SELECT DOACTE.*, COALESCE(ArrestingOfficerCTE.ArrestingOfficerCompany, 'NULL')AS ArrestingOfficerCompany, COALESCE(ArrestingOfficerCTE.ArrestingOfficerName, 'NULL') AS ArrestingOfficerName, SolicitorCTE.SolicitorName, PivotCTE.[Date_Arrest], dbo.GetImagebyId(PivotCTE.[Graphic_Client]) as Photo, PivotCTE.[Ticket_1], PivotCTE.[Ticket_2], PivotCTE.[Ticket_3], PivotCTE.[Ticket_4], PivotCTE.[Ticket_5], PivotCTE.[Charge_1], PivotCTE.[Charge_2], PivotCTE.[Charge_3], PivotCTE.[Charge_4], PivotCTE.[Charge_5]
            FROM DOACTE
            INNER JOIN 
            PivotCTE
            ON DOACTE.Id = PivotCTE.Id
            INNER JOIN
            SolicitorCTE
            ON DOACTE.Id = SolicitorCTE.Id
            INNER JOIN
            ArrestingOfficerCTE
            ON DOACTE.Id = ArrestingOfficerCTE.Id
            WHERE DOACTE.RowNumber = 1
            AND ArrestingOfficerCTE.RowNumber = 1

        ELSE

        DELETE SelectionCache 
            WHERE UUID = @UUID
            AND   TableCode = @TableCode
    END
4

3 に答える 3

1

オプションの結果については、結合を残すことができます。また、左結合にもかかわらずレコードが除外されないように、逮捕警官のヌル チェックを where コールに追加する必要がありました。

SELECT DOACTE.*, COALESCE(ArrestingOfficerCTE.ArrestingOfficerCompany, 'NULL')AS ArrestingOfficerCompany, COALESCE(ArrestingOfficerCTE.ArrestingOfficerName, 'NULL') AS ArrestingOfficerName, SolicitorCTE.SolicitorName, PivotCTE.[Date_Arrest], dbo.GetImagebyId(PivotCTE.[Graphic_Client]) as Photo, PivotCTE.[Ticket_1], PivotCTE.[Ticket_2], PivotCTE.[Ticket_3], PivotCTE.[Ticket_4], PivotCTE.[Ticket_5], PivotCTE.[Charge_1], PivotCTE.[Charge_2], PivotCTE.[Charge_3], PivotCTE.[Charge_4], PivotCTE.[Charge_5]
            FROM DOACTE
            INNER JOIN 
            PivotCTE
            ON DOACTE.Id = PivotCTE.Id
            LEFT JOIN
            SolicitorCTE
            ON DOACTE.Id = SolicitorCTE.Id
            LEFT JOIN
            ArrestingOfficerCTE
            ON DOACTE.Id = ArrestingOfficerCTE.Id
            WHERE DOACTE.RowNumber = 1
            AND ( ArrestingOfficerCTE.RowNumber = 1 or ArrestingOfficerCTE.RowNumber is null )
于 2013-06-18T20:52:36.667 に答える
0

これはほとんどliebs19の答えなので、彼が最初にそこに着いたので、私は彼に賛成票を投じました。答えはLEFT JOIN、あなたがどこにいるかにかかっていると思いますINNER。私はあなたのクエリを書き直したので、何が起こっているのかを実際に理解することができ、あなたが望むかもしれないし、望まないかもしれないいくつかの変更を加えました。

私は部分的にフォーマットが異なるため、部分的にはあなたよりも多くの行があります。部分的には、一時テーブルを使用して、あなたが約4回行うことを1回行うためです。CTE に関することは、このようにスタックすると、非常に危険なパフォーマンスが得られる可能性が高いということです。CTE は基本的にオンザフライ ビューのように動作し、その SQL はほぼどこでも繰り返されます。私はあなたの制限を取り、[File]それを一時テーブルに移動しています。RowNumber次に、それを別のものにピボットしています(これにより、 being に基づいて物事がさらに制限される1ためです。次に、これを最後に2つのCTEで使用して、最終結果に入れます.

最後にSELECT * ...悪です。何かを探し回っているときにのみ使用します。このようにsprocに入れると、スキーマやCTEなどが変更されると問題が発生します。sproc を作成するときは、すべての列に名前を付けてください。

これが役に立たない場合は、無視してかまいません。

ALTER PROCEDURE [dbo].[GetRollCallData] 
    @Ids        VARCHAR(255),
    @LexiconId  INT,
    @UUID       UNIQUEIDENTIFIER,
    @ReadOnly   INT
AS
BEGIN
    DECLARE @TableCode INT = 58;

    IF @Ids <> ''
    BEGIN
        EXEC InsertInSelectionCache @Ids, @UUID, @TableCode, 0

        IF @ReadOnly = 1
        BEGIN
            SELECT
                -- Add any other fully qualified columns. * is evil for sprocs. Only good for poking around in your own queries.
                AllFiles.Id
            INTO #SelectionFile
            FROM 
                [File] AllFiles
                INNER JOIN SelectionCache Cache
                    ON Cache.RecordId = AllFiles.Id
                    AND Cache.UUID = @UUID
                    AND Cache.TableCode = @TableCode -- this is the code for File table 
            WHERE
                AllFiles.Id <> 0

            ;WITH DOACTE AS
            (
                SELECT 
                    ROW_NUMBER() OVER(PARTITION BY SelectionFile.Id ORDER BY CustomRecordsetId DESC) AS RowNumber
                    , SelectionFile.Id AS FileId
                    -- [Replace with any other columns that you selected from [File] at the top.]
                    , Lexicon.Label AS FileTypeLabel
                    , [People].DefaultPhone
                    , [People].InvertedName
                    , CustomField.Name AS FieldLabel
                    , CustomFieldValue.Value AS FieldValue
                FROM 
                    #SelectionFile SelectionFile
                    INNER JOIN FileType2Lexicon Lexicon
                        ON Lexicon.FileTypeId = SelectionFile.FileTypeId
                        AND Lexicon.LexiconId = @LexiconId
                    INNER JOIN [People]
                        ON [People].ClientIdString = SelectionFile.ClientIdString
                    INNER JOIN [CustomRecordSet]
                        ON [CustomRecordset].RecordId = SelectionFile.Id
                    INNER JOIN CustomFieldValue
                        ON [CustomRecordset].Id = CustomFieldValue.CustomRecordsetId
                        AND CustomFieldValue.Value <> ''
                    INNER JOIN [CustomField2Lexicon]
                        ON CustomField2Lexicon.CustomFieldId = CustomFieldValue.CustomFieldId
                    INNER JOIN [CustomField]
                        ON CustomField.Id = CustomField2Lexicon.CustomFieldId
            )
            SELECT 
                Pvt.FileId
                -- [Replace with any other columns that you selected from DOACTE you want to propagate to the end.]
                , Pvt.[Date_Arrest]
                , Pvt.[Graphic_Client]
                , Pvt.[Ticket_1]
                , Pvt.[Ticket_2]
                , Pvt.[Ticket_3]
                , Pvt.[Ticket_4]
                , Pvt.[Ticket_5]
                , Pvt.[Charge_1]
                , Pvt.[Charge_2]
                , Pvt.[Charge_3]
                , Pvt.[Charge_4]
                , Pvt.[Charge_5]
            INTO #PivotedFile
            FROM
            (
                SELECT 
                    FileId
                    -- [Replace with any other columns that you selected from DOACTE you want to propagate to the end.]
                    , FieldLabel
                    , FieldValue 
                    , FieldLabel AS PivotFieldLabel
                    , FieldValue AS PivotFieldValue
                FROM 
                    DOACTE
                WHERE 
                    RowNumber = 1
            ) AS Source
            PIVOT
            (
                MAX(PivotFieldValue) 
                FOR PivotFieldLabel 
                IN 
                (
                    [Date_Arrest]
                    , [Graphic_Client]
                    , [Ticket_1]
                    , [Ticket_2]
                    , [Ticket_3]
                    , [Ticket_4]
                    , [Ticket_5]
                    , [Charge_1]
                    , [Charge_2]
                    , [Charge_3]
                    , [Charge_4]
                    , [Charge_5]
                )
            ) as Pvt

            ;WITH SolicitorCTE AS
            (
                SELECT 
                    [People].Name AS SolicitorName
                    , SelectedFiles.FileId
                FROM 
                    #PivotedFile SelectedFiles
                    INNER JOIN [People2File]
                        ON [People2File].FileId = SelectedFiles.FileId
                    INNER JOIN [Role2Lexicon]
                        ON [Role2Lexicon].RoleId = [People2File].RoleId
                        AND [Role2Lexicon].Label = 'Solicitor'
                    INNER JOIN [People]
                        ON [People].Id = [People2File].PeopleId
            )
            , ArrestingOfficerCTE AS
            (
                SELECT 
                    ROW_NUMBER() OVER(PARTITION BY SelectionFile.Id ORDER BY [People].InvertedName ASC) AS RowNumber
                    , [People].Name AS ArrestingOfficerName
                    , [People].CompanyName AS ArrestingOfficerCompany
                    , SelectedFiles.FileId
                FROM 
                    #PivotedFile SelectedFiles
                    INNER JOIN [People2File]
                        ON [People2File].FileId = SelectedFiles.FileId
                    INNER JOIN [Role2Lexicon]
                        ON [Role2Lexicon].RoleId = [People2File].RoleId
                        AND [Role2Lexicon].Label = 'Arresting Officer'
                    INNER JOIN [People]
                        ON [People].Id = [People2File].PeopleId
            )
            SELECT 
                SelectedFiles.Id
                -- [Replace with any other columns that you selected from DOACTE you want to propagate to the end.]
                , COALESCE(ArrestingOfficerCTE.ArrestingOfficerCompany, 'NULL') AS ArrestingOfficerCompany
                , COALESCE(ArrestingOfficerCTE.ArrestingOfficerName, 'NULL') AS ArrestingOfficerName
                , SolicitorCTE.SolicitorName
                , SelectedFiles.[Date_Arrest]
                , dbo.GetImagebyId(SelectedFiles.[Graphic_Client]) as Photo
                , SelectedFiles.[Ticket_1]
                , SelectedFiles.[Ticket_2]
                , SelectedFiles.[Ticket_3]
                , SelectedFiles.[Ticket_4]
                , SelectedFiles.[Ticket_5]
                , SelectedFiles.[Charge_1]
                , SelectedFiles.[Charge_2]
                , SelectedFiles.[Charge_3]
                , SelectedFiles.[Charge_4]
                , SelectedFiles.[Charge_5]
            FROM #PivotedFile SelectedFiles
                LEFT JOIN SolicitorCTE
                    ON SelectedFiles.FileId = SolicitorCTE.FileId
                LEFT JOIN ArrestingOfficerCTE
                    ON SelectedFiles.FileId = ArrestingOfficerCTE.FileId
                    AND ArrestingOfficerCTE.RowNumber = 1

        DROP TABLE #SelectionFile
        DROP TABLE #PivotedFile
        END
    ELSE
        DELETE SelectionCache 
        WHERE 
            UUID = @UUID
            AND TableCode = @TableCode
    END
END

(使用する場合は、-- [Replace...]コメントをお読みください。

于 2013-06-18T22:21:38.227 に答える