当第一个不总是 returns 特定行的值时,如何将一个 select 与另一个连接?

How to join one select with another when the first one not always returns a value for specific row?

我有一个复杂的查询来检索一些结果:

EDITED QUERY(添加了 UNION ALL):

SELECT  t.*
FROM (

    SELECT  
        dbo.Intervencao.INT_Processo, analista, 
        ETS.ETS_Sigla, ATC.ATC_Sigla, PAT.PAT_Sigla, dbo.Assunto.SNT_Peso,
        CASE 
            WHEN ETS.ETS_Sigla = 'PE' AND (PAT.PAT_Sigla = 'LIB' OR PAT.PAT_Sigla = 'LBR') THEN (0.3*SNT_Peso) 
            WHEN ETS.ETS_Sigla = 'CD' THEN (0.3*SNT_Peso)*0.3  
            ELSE SNT_Peso
        END AS PESOAREA,
        CASE 
            WHEN a.max_TEA_FimTarefa IS NULL THEN a.max_TEA_InicioTarefa
            ELSE a.max_TEA_FimTarefa
        END AS DATA_INICIO_TERMINO,
        ROW_NUMBER() OVER (PARTITION BY ATC.ATC_Sigla, a.SRV_Id ORDER BY TEA_FimTarefa DESC) AS seqnum 
    FROM dbo.Tarefa AS t

    INNER JOIN (
        SELECT 
            MAX(dbo.TarefaEtapaAreaTecnica.TEA_InicioTarefa) AS max_TEA_InicioTarefa,
            MAX (dbo.TarefaEtapaAreaTecnica.TEA_FimTarefa) AS max_TEA_FimTarefa,
            dbo.Pessoa.PFJ_Descri AS analista, dbo.AreaTecnica.ATC_Id, dbo.Tarefa.SRV_Id
        FROM dbo.TarefaEtapaAreaTecnica 
        LEFT JOIN dbo.Tarefa ON dbo.TarefaEtapaAreaTecnica.TRF_Id = dbo.Tarefa.TRF_Id
        LEFT JOIN dbo.AreaTecnica ON dbo.TarefaEtapaAreaTecnica.ATC_Id = dbo.AreaTecnica.ATC_Id 
        LEFT JOIN dbo.ServicoAreaTecnica ON dbo.TarefaEtapaAreaTecnica.ATC_Id = dbo.ServicoAreaTecnica.ATC_Id 
            AND dbo.Tarefa.SRV_Id = dbo.ServicoAreaTecnica.SRV_Id
        INNER JOIN dbo.Pessoa ON dbo.Pessoa.PFJ_Id = dbo.ServicoAreaTecnica.PFJ_Id_Analista
        GROUP BY dbo.AreaTecnica.ATC_Id, dbo.Tarefa.SRV_Id, dbo.Pessoa.PFJ_Descri
    ) AS a ON t.SRV_Id = a.SRV_Id

    INNER JOIN dbo.TarefaEtapaAreaTecnica AS TarefaEtapaAreaTecnica_1 ON 
        t.TRF_Id = TarefaEtapaAreaTecnica_1.TRF_Id 
        AND a.ATC_Id = TarefaEtapaAreaTecnica_1.ATC_Id 
        AND a.max_TEA_InicioTarefa = TarefaEtapaAreaTecnica_1.TEA_InicioTarefa
    LEFT JOIN AreaTecnica ATC ON TarefaEtapaAreaTecnica_1.ATC_Id = ATC.ATC_Id
    LEFT JOIN Etapa ETS ON TarefaEtapaAreaTecnica_1.ETS_Id = ETS.ETS_Id
    LEFT JOIN ParecerTipo PAT ON TarefaEtapaAreaTecnica_1.PAT_Id = PAT.PAT_Id
    LEFT OUTER JOIN dbo.Servico ON a.SRV_Id = dbo.Servico.SRV_Id
    INNER JOIN dbo.Intervencao ON dbo.Servico.INT_Id = dbo.Intervencao.INT_Id
    LEFT JOIN dbo.Assunto ON dbo.Servico.SNT_Id = dbo.Assunto.SNT_Id

) t

结果如下:

效果很好,问题是我被问到如果此查询中不存在一行,则它必须包含来自另一个 table (ServicoAreaTecnica) 的值,所以我得到了此查询other table 基于第一个查询的关键信息。所以如果我 UNION ALL 我得到这个:

Query1 + 

UNION ALL

     SELECT INN.INT_Processo, 
            PES.PFJ_Descri,
            NULL, --ETS.ETS_Sigla, 
            ART.ATC_Sigla, 
            NULL ,--PAT.PAT_Sigla,
            ASS.SNT_Peso,
            NULL, --PESOAREA
            NULL, --DATA_INICIO_TERMINO
            NULL --seqnum

     FROM dbo.ServicoAreaTecnica AS SAT
     INNER JOIN dbo.AreaTecnica AS ART ON ART.ATC_Id = SAT.ATC_Id
     INNER JOIN dbo.Servico AS SER ON SER.SRV_Id = SAT.SRV_Id
     INNER JOIN dbo.Assunto AS ASS ON ASS.SNT_Id = SER.SNT_Id
     INNER JOIN dbo.Intervencao AS INN ON INN.INT_Id = SER.INT_Id
     INNER JOIN dbo.Pessoa AS PES ON PES.PFJ_Id = SAT.PFJ_Id_Analista

结果如下:

所以我想做的是删除第 1 行,因为第 2 行存在于第一个查询中,我想这次我得到了更好的解释。结果应该只有第 1 行,只有当查询 1 没有检索到特定 INN.INT_Processo.

的行时,才会出现第 2 行

谢谢!

你的代码很难阅读,因为所有东西的名字都很长(老实说,它们使用的是我不会说的语言,这也让阅读变得更加困难)。

但是如何:用 LEFT JOIN 替换您的 INNER JOIN,添加更多 LEFT JOIN 以绘制备选表格,并为每个表格引入 ISNULL 子句您想要结果中的变量?

如果您执行类似 ... Query1 Right Join Query2 On ... 的操作,则应该只获取查询 2 中未出现在查询 1 中的行。

好的,有两种方法可以减少您的记录集。鉴于您已经编写了生成带有额外行的 table 的代码,最简单的方法可能是仅添加代码来减少它:

Select * from 
    (Select *
      , Row_Number() over 
           (partition by IntProcesso, Analista order by ISNULL(seqnum, 0) desc) as RN
    from MyResults) a
where RN = 1

这会将 row_number 1 分配给来自第一个查询的任何行,或分配给第二个查询中在第一个查询中没有匹配项的任何行,然后过滤掉额外的行。

您也可以按照其他人的建议,将外部联接与 isnullcoalesce 结合使用。像这样:

Select ISNULL(a.IntProcesso, b.IntProcesso) as IntProcesso
    , ISNULL(a.Analista, b.Analista) as Analista
    , ISNULL(a.ETSsigla, b.ETSsigla) as ETSsigla
    [repeat for the rest of your columns]
from Table1 a
full outer join Table2 b
on a.IntProcesso = b.IntProcesso and a.Analista = b.Analista