How do I aggregate 3 columns that are different with MIN(DATE)?

68 Views Asked by At

I'm facing a simple problem here that I can't solve, I have this query:

     SELECT 
            MIN(TEA_InicioTarefa),
            PFJ_Id_Analista,
            ATC_Id, 
            SRV_Id
        FROM  
            dbo.TarefaEtapaAreaTecnica 
   INNER JOIN Tarefa t ON t.TRF_Id = TarefaEtapaAreaTecnica.TRF_Id
   WHERE SRV_Id = 88  
   GROUP BY SRV_Id, ATC_Id, PFJ_Id_Analista
   ORDER BY ATC_Id ASC

It returns me this:

enter image description here

I was able to group it a little with GROUP BY SRV_Id, ATC_Id, PFJ_Id_Analista that gave me these 8 records, but as you can see some PFJ_Id_Analista are different.

What I want is to select only the early date of each SRV_Id and ATC_Id, the PFJ_Id_Analista don't need to grup, if I remove PFJ_Id_Analista from the grouping the query works, but I need the column.

For eg.: between row number 2 and 3 I want only the early date, so it will be row 2. The same goes for rows 5 to 8, I want only row 6.

DDL for TarefaEtapaAreaTecnica (important key: TRF_Id)

CREATE TABLE [dbo].[TarefaEtapaAreaTecnica](
    [TEA_Id] [int] IDENTITY(1,1) NOT NULL,
    **[TRF_Id] [int] NOT NULL,**
    [ETS_Id] [int] NOT NULL,
    [ATC_Id] [int] NOT NULL,
    [TEA_Revisao] [int] NOT NULL,
    [PFJ_Id_Projetista] [int] NULL,
    [TEA_DoctosQtd] [int] NULL,
    [TEA_InicioTarefa] [datetime2](7) NULL,
    [PFJ_Id_Analista] [int] NULL,
    [TEA_FimTarefa] [datetime2](7) NULL,
    [TEA_HorasQtd] [numeric](18, 1) NULL,
    [TEA_NcfQtd] [int] NULL,
    [PAT_Id] [int] NULL

DDL for Tarefa (important keys TRF_Id and SRV_Id (which I need it)):

CREATE TABLE [dbo].[Tarefa](
    **[TRF_Id] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL,**
    **[SRV_Id] [int] NOT NULL,**
    [TRT_Id] [int] NOT NULL,
    [TRF_Descr] [varchar](255) NULL,
    [TRF_Entrada] [datetime] NOT NULL,
    [TRF_DoctosQtd] [int] NOT NULL,
    [TRF_Devolucao] [datetime] NULL,
    [TRF_NcfQtd] [int] NULL,
    [TRF_EhDocInsuf] [bit] NULL,
    [TRF_Observ] [varchar](255) NULL,
    [TRF_AreasTrfQtd] [int] NULL,
    [TRF_AreasTrfLiqQtd] [int] NULL

Thanks a lot.

EDIT: CORRECT QUERY

Based on @Gordon Linoff post:

select t.TEA_InicioTarefa, t.PFJ_Id_Analista, t.ATC_Id, t.SRV_Id
from (select t.*,  
             row_number() over (partition by ATC_Id, SRV_Id
                                order by TEA_InicioTarefa) as seqnum, ta.SRV_Id 
      from dbo.TarefaEtapaAreaTecnica t
      inner join dbo.Tarefa ta on t.TRF_Id = ta.TRF_Id
     ) t
where seqnum = 1 AND t.SRV_Id = 88
2

There are 2 best solutions below

0
On BEST ANSWER

Just use window functions:

select t.*
from (select t.*,
             row_number() over (partition by ATC_Id, SRV_Id
                                order by ini) as seqnum
      from dbo.TarefaEtapaAreaTecnica t
     ) t
where seqnum = 1;

This is really an example of filtering, not aggregation. The problem is getting the right value to filter on.

0
On

Then get the grouping first and then do a JOIN with it like

     SELECT 
            x.Min_TEA_InicioTarefa,
            t.PFJ_Id_Analista,
            t.ATC_Id, 
            t.SRV_Id
        FROM  
            dbo.TarefaEtapaAreaTecnica t
   INNER JOIN Tarefa ta ON ta.TRF_Id = t.TRF_Id
   INNER JOIN (
     select SRV_Id, MIN(TEA_InicioTarefa) as Min_TEA_InicioTarefa
      from dbo.TarefaEtapaAreaTecnica
      GROUP BY SRV_Id
     ) x ON t.SRV_Id = x.SRV_Id
   WHERE t.SRV_Id = 88  
   ORDER BY t.ATC_Id ASC;