2013-06-14 2 views
0

보고서 작성기에서 SSRS에 사용할 필드 범위를 통합하는 저장 프로 시저가 SQL Server에 있습니다. 프로 시저에 FileId가 입력되면 논리가 작동합니다. File이 Solicitor and Arresting Officer 필드를 찾거나 참조 할 수 없을 때까지 의도 한대로 작동합니다.CTE가 해결되지 않는 경우에도 결과가 반환됩니다.

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 
+0

한 가지 해결책은 CTE 쿼리의 행 수를 계산하는 것이고 비어있는 경우 NULL/기본 행을 선택하는 것입니다. – Abyssul

답변

1

당신은 선택 결과에 가입 남아 있습니다. 또한 왼쪽 구속에도 불구하고 기록을 제외시키지 않기 위해 체포 담당자에게 널 수표를 추가해야합니다.

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) 
+0

이것이 옳습니다. LEFT JOIN은 내 문제를 해결합니다. 또한 ArrestingOfficerCTE에 0 행이있을 때 고려해야 할 WHERE 절 (ArrestingOfficerCTE.RowNumber <2 OR ArrestingOfficerName IS NULL)을 변경해야했습니다. – Abyssul

0

당신은 시도 할 수

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] 
into #Results 
      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 

if ((select cout(*) from #Results) = 0) 
begin 

insert into #Results 
     select 
      .......your default values...... 

end 

select * from #Results 

drop table #Results 
+0

나는 "당신의 디폴트 값"에 무엇을 넣을 지 정말로 모른다. SolicitorCTE 및 ArrestingOfficerCTE에 대한 CTE는 파일에서 각각의 Solicitor/ArrestingOfficer 역할을 찾지 못한 경우 행을 반환하지 않습니다. 따라서 최종 쿼리는 어떤 행으로도 해결되지 않습니다. 쿼리가 데이터베이스의 다른 테이블에있는 FileId를 확인하는 부분에 대한 기본값 만 필요하며 반환되는 모든 열의 기본값은 아닙니다. – Abyssul

+0

채우려는 값을 선택하고 나머지 값은 null을 입력하십시오. 'select '를 value1, null을 value2, 1234 and value3' 등 ... – liebs19

+0

반환하는 질의 부분에 대해서'INNER JOIN' 대신'LEFT JOIN'으로 변경했는지 궁금합니다. 당신에게 당신의 대답을 줄 경우 결과가 없습니다. 시도해 볼 새로운 답변으로 게시하겠습니다. – liebs19

0

이것은 거의 liebs19의 대답입니다. 그래서 나는 그가 거기에 먼저 도착한 이후로 그의 것을 upvoted. 나는 대답이 인 곳에서 LEFT JOIN ing이라고 생각합니다. 귀하의 질의를 다시 작성하여 실제로 무슨 일이 벌어지고 있는지 이해할 수 있었고, 당신이 원하거나 원하지 않을 수도있는 몇 가지 변화를 만들었으므로 유용 할 경우를 대비하여 여기에 남겨 두겠습니다.

광산은 내가 다르게 포맷하기 때문에 부분적으로 더 많은 선을 사용합니다. 부분적으로는 내가 네가하는 일을 한 번하기 위해 임시 테이블을 사용하기 때문입니다. CTE의 장점은 이러한 스택을 사용하면 성능이 크게 저하 될 수 있다는 것입니다. CTE의 행동은 기본적으로 실시간보기와 같으며 SQL은 모든 곳에서 반복됩니다. 귀하의 제한 [File]을 가져와 임시 테이블로 옮깁니다. 그럼 난 RowNumber1 인에 따라이 더 제한 일 이후 (다른 하나에 그것을 선회하고있다. 그럼 난 그냥 말과 최종 결과에 2 CTE의 이것을 사용합니다.

마지막을 SELECT * ... 악된다. I 내가 뭔가를 쿼리 주위에 파고있어 때만 사용하십시오.이 같은 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...] 설명을 읽으십시오.

관련 문제