Sql 如何过滤重复的行并对数据进行排序,而不包括SELECT上的ORDER BY字段?
我在SQL Server上声明了以下存储过程:Sql 如何过滤重复的行并对数据进行排序,而不包括SELECT上的ORDER BY字段?,sql,sql-server,Sql,Sql Server,我在SQL Server上声明了以下存储过程: ALTER PROCEDURE [dbo].[ContratoMarcoGP_FuerzaTrabajo] @IdContratoMarco INT = NULL, @Desde DATETIME, @Hasta DATETIME, @IdSede INT, @IdIdioma INT, @IdProveedor INT AS BEG
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 keywork,但它告诉我需要在SELECT中包含ORDER BY中指定的字段,我不希望这样做。我的意思是,我只需要包括我在SELECT子句中指定的字段,因为它在C数据表中返回这些数据。
如何按此字段对数据进行排序并过滤重复的行,而不在SELECT中包含新字段?是否可能在两个步骤中使用子查询来筛选所需字段?使用group by,然后在order by中包含聚合函数,而不是使用distinct。以下是基于您的查询的模板:
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中,应始终包含字段的长度。默认值因上下文而异,依赖默认值可能会产生难以发现的bug。我不太理解这个问题,但至少有一部分: 但它告诉我,我需要在SELECT中包含orderby中指定的字段,我不希望这样做 也许是一张临时桌子 例如:如果需要此选项:
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
删除ORDER BY并在DataTable的C中执行?以下是两个简单的蛮力答案。。。1去掉order by并在c代码中进行排序。2添加列,然后将整个内容包装在子选择中。但是,你最好还是按照戈登的答案去做谢谢Tanner,这可能是另一个好方法。我想这样做,但我更喜欢在数据库中有完整的逻辑。那些列当前不在SELECT中,但以ORDER BY的形式出现-对于SELECT子句中所有列都匹配的行,它们可能包含多个不同的值。DISTINCT将把这些列减少为一行-服务器如何知道这些列使用什么值?Gordon的答案解决了我的问题。在这一行中,我的意思是,如果使用DISTINCT关键字,则需要在SELECT上写入在ORDERBY子句上设置的任何字段。无论如何谢谢你!也许我可以帮助其他人:当Gordon写他的答案时,我正忙着测试这个问题,对于你写的那行,应该有F5'ed:P,这解决了这个问题,因为在我的例子中,我不会得到最终结果。不管怎样,很高兴看到你得到了答案:非常感谢戈登!!它以一种非常有效的方式解决了我的问题。这是一个非常好的回答。