如何在不包含SELECT上的ORDER BY字段的情况下过滤重复的行和排序数据?

时间:2014-03-19 15:29:38

标签: sql sql-server

我在SQL Server上声明了以下存储过程:

ALTER PROCEDURE [dbo].[ContratoMarcoGP_FuerzaTrabajo]
@IdContratoMarco    INT = NULL,
@Desde              DATETIME,
@Hasta              DATETIME,
@IdSede             INT,
@IdIdioma           INT,
@IdProveedor        INT
AS
BEGIN

SELECT 
            CAST(PD.[IdPeriodoDetalle] AS VARCHAR) + '-' + CAST(E.[IdEspecialidad] AS VARCHAR) AS [IdUnico], -- generado para el storetable
            PD.[IdPeriodoDetalle],
            M.[Descripcion] + ' - ' + CAST(PD.[Anio] AS CHAR(4)) AS [PeriodoDetalle], 
            E.[IdEspecialidad], 
            E.[Descripcion] AS [Especialidad], 
            CAST(
                (CASE 
                    WHEN CMH.[Horas] IS NULL THEN 0
                    ELSE CMH.[Horas]
                END) 
            AS INT)AS [Horas]
        FROM 
            [PeriodoDetalle] PD 
            INNER JOIN ProveedorPersona PP ON PP.IdProveedor = @IdProveedor
            INNER JOIN [Especialidad] E ON E.IdEspecialidad = PP.IdEspecialidad
            LEFT JOIN [ContratoMarcoHoras] CMH ON E.[IdEspecialidad] = CMH.[IdEspecialidad] AND PD.[IdPeriodoDetalle] = CMH.[IdPeriodoDetalle] AND CMH.[IdContratoMarco] = @IdContratoMarco -- traigo las horas cargadas sólo para el contrato indicado.
            INNER JOIN [Mes] M ON PD.[Mes] = M.[IdMes] AND M.[IdIdioma] = @IdIdioma
        WHERE 
        (   
            [FechaDesdeGP] BETWEEN @Desde AND @Hasta
        OR  
            [FechaHastaGP] BETWEEN @Desde AND @Hasta
        OR
            (
                @Desde BETWEEN [FechaDesdeGP] AND [FechaHastaGP]
            OR
                @Hasta BETWEEN [FechaDesdeGP] AND [FechaHastaGP]
            )
        )
        AND
            PD.[IdSede] = @IdSede
        AND
            E.[IdIdioma] = @IdIdioma
        AND 
            PP.IdProveedor = @IdProveedor   
        ORDER BY 
            PD.[Anio], PD.[Mes]
END

问题是,当我用一些参数调用这个过程时,它会返回一些重复的行,所以我想使用DISTINCT键,但它告诉我需要在SELECT中包含指定的字段ORDER BY,我不想要它。我的意思是,我只需要包含我在SELECT子句中指定的字段,因为它在C#DataTable上返回此数据。 如何通过此字段对此数据进行排序并过滤重复的行而不在SELECT中包含新字段?是否可以使用子查询分两步过滤所需的字段?

2 个答案:

答案 0 :(得分:2)

不使用distinct,而是使用group by,然后在order by中包含聚合函数。以下是基于您的查询的模板:

select CAST(PD.[IdPeriodoDetalle] AS VARCHAR(255)) + '-' + CAST(E.[IdEspecialidad] AS VARCHAR(255)) AS [IdUnico],
       . . .
from [PeriodoDetalle] PD 
     . . .
where . . .
group by <all the columns in the select>
order by max(PD.[Anio]), max(PD.[Mes]);

请注意,我添加了varchar()的长度参数。在SQL Server中,您应始终包含字段的长度。默认值根据上下文而有所不同,依赖于默认值可能会导致很难找到错误。

答案 1 :(得分:0)

我不认为我完全理解这个问题,但至少有一部分是这样的:

&#34;但它告诉我,我需要在SELECT中包含ORDER BY中指定的字段,我不想要它。&#34;

也许是临时表?

例如:如果你想要这个:

select distinct date,value from dbo.TAB_A2
order by id

那会产生错误。代替:

create table #tab_a3(id int, date datetime,value int)

insert into #tab_A3
    select distinct id, date,value 
    from dbo.TAB_A2
    order by id

select date,value from #tab_A3