如何仅对sql Query中的某些列使用group?

时间:2015-07-22 15:43:11

标签: sql sql-server sql-server-2008 c#-4.0 group-by

以下查询返回550条记录,然后我通过linq对控制器中的某些列进行分组。但是,如何在SQL查询本身中实现“分组依据”逻辑?此外,在分组后,我只需向用户显示150个结果。

当前SQL查询:

SELECT DISTINCT 
  l.Id AS LoadId
  , l.LoadTrackingNumber AS LoadDisplayId
  , planningType.Text AS PlanningType
  , loadStatus.Id AS StatusId
  , loadWorkRequest.Id AS LoadRequestId
  , loadStatus.Text AS Status
  , routeIds.RouteIdentifier AS RouteName
  , planRequest.Id AS PlanId 
  , originPartyRole.Id AS OriginId
  , originParty.Id AS OriginPartyId
  , originParty.LegalName AS Origin
  , destinationPartyRole.Id AS DestinationId
  , destinationParty.Id AS DestinationPartyId
  , destinationParty.LegalName AS Destination
  , COALESCE(firstSegmentLocation.Window_Start, originLocation.Window_Start) AS StartDate
  , COALESCE(firstSegmentLocation.Window_Start, originLocation.Window_Start) AS BeginDate
  , destLocation.Window_Finish AS EndDate
    AS Number
    FROM Domain.Loads (NOLOCK) AS l
    INNER JOIN dbo.Lists (NOLOCK) AS loadStatus ON l.LoadStatusId = loadStatus.Id
    INNER JOIN Domain.Routes (NOLOCK) AS routeIds ON routeIds.Id = l.RouteId

    INNER JOIN Domain.BaseRequests (NOLOCK) AS loadWorkRequest ON loadWorkRequest.LoadId = l.Id 
    INNER JOIN Domain.BaseRequests (NOLOCK) AS planRequest ON planRequest.Id = loadWorkRequest.ParentWorkRequestId
    INNER JOIN Domain.Schedules AS planSchedule ON planSchedule.Id = planRequest.ScheduleId

    INNER JOIN Domain.Segments (NOLOCK) os on os.RouteId = routeIds.Id AND os.[Order] = 0
    INNER JOIN Domain.LocationDetails (NOLOCK) AS originLocation ON originLocation.Id = os.DestinationId
    INNER JOIN dbo.EntityRoles (NOLOCK) AS originPartyRole ON originPartyRole.Id = originLocation.DockRoleId
    INNER JOIN dbo.Entities (NOLOCK) AS originParty ON originParty.Id = originPartyRole.PartyId

    INNER JOIN Domain.LocationDetails (NOLOCK)  AS destLocation ON destLocation.Id = routeIds.DestinationFacilityLocationId  
    INNER JOIN dbo.EntityRoles (NOLOCK)  AS destinationPartyRole ON destinationPartyRole.Id = destLocation.DockRoleId
    INNER JOIN dbo.Entities (NOLOCK)  AS destinationParty ON destinationParty.Id = destinationPartyRole.PartyId

    INNER JOIN dbo.TransportationModes (NOLOCK) lictm on lictm.Id = l.LoadInstanceCarrierModeId
    INNER JOIN dbo.EntityRoles  (NOLOCK) AS carrierPartyRole ON lictm.CarrierId = carrierPartyRole.Id 
    INNER JOIN dbo.Entities  (NOLOCK) AS carrier ON carrierPartyRole.PartyId = carrier.Id 

    INNER JOIN dbo.EntityRoles  (NOLOCK) AS respPartyRole ON l.ResponsiblePartyId = respPartyRole.Id 
    INNER JOIN dbo.Entities  (NOLOCK) AS respParty ON respPartyRole.PartyId = respParty.Id 
    INNER JOIN Domain.LoadOrders (NOLOCK) lo ON lo.LoadInstanceId = l.Id 
    INNER JOIN Domain.Orders  (NOLOCK) AS o ON lo.OrderInstanceId = o.Id

    INNER JOIN Domain.BaseRequests  (NOLOCK) AS loadRequest ON loadRequest.LoadId = l.Id 

    --Load Start Date
    LEFT JOIN Domain.Segments (NOLOCK) AS segment ON segment.RouteId = l.RouteId AND segment.[Order] = 0
    LEFT JOIN Domain.LocationDetails (NOLOCK) AS firstSegmentLocation ON firstSegmentLocation.Id = segment.DestinationId

    LEFT JOIN dbo.Lists (NOLOCK) AS planningType ON l.PlanningTypeId = planningType.Id

    LEFT JOIN dbo.EntityRoles (NOLOCK)  AS billToRole ON o.BillToId = billToRole.Id
    LEFT JOIN dbo.Entities  (NOLOCK) AS billTo ON billToRole.PartyId = billTo.Id                     

 WHERE o.CustomerId in (34236) AND originLocation.Window_Start >= '07/19/2015 00:00:00' AND originLocation.Window_Start < '07/25/2015 23:59:59' AND l.IsHistoricalLoad = 0
AND loadStatus.Id in (285, 286,289,611,290)
AND loadWorkRequest.ParentWorkRequestId IS NOT NULL
AND routeIds.RouteIdentifier IS NOT NULL
AND (planSchedule.EndDate IS NULL OR (planSchedule.EndDate is not null and CAST(CONVERT(varchar(10), planSchedule.EndDate,101) as datetime) > CAST(CONVERT(varchar(10),GETDATE(),101) as datetime))) ORDER BY l.Id DESC

LINQ:

//Get custom grouped data
var loadRequest = (from lq in returnList
                        let loadDisplayId = lq.LoadDisplayId
                        let origin = lq.OriginId //get this  origin for route
                        let destination = lq.DestinationId // get this destination for route
                   group lq by new
                   {
                       RouteId = lq.RouteName,
                       PlanId = lq.PlanId,
                       Origin = lq.OriginId,
                       Destination = lq.DestinationId
                   }
                   into grp
                   select new
                   {
                       RouteId = grp.Key.RouteId,
                       PlanId = grp.Key.PlanId,
                       Origin = grp.Key.Origin,
                       Destination = grp.Key.Destination,
                       Loads = (from l in grp select l)
                   }).OrderBy(x => x.Origin).ToList();

2 个答案:

答案 0 :(得分:0)

我猜你想要按第1列分组,但在Select中包含第2列和第3列。使用组你不能这样做。但是,您可以使用OVER()运算符使用T-SQL窗口函数执行此操作。既然你没有说你想如何聚合,我就不能提供一个例子。但是看看T-SQL窗口函数。这个article可能会帮助您入门。

答案 1 :(得分:0)

您需要了解GROUP BY的一个重要事项是,您必须假设GROUP BY列表之外的每一列都有多个值。在您的情况下,您必须假设Column1的每个值都有Column2Column3的多个值,都被视为一个组。

如果您希望查询处理任何这些列,则必须指定如何处理这些多个值。

以下是您的一些选择:

  • 为组中的列选择最小值或最大值 - 使用MIN(...)MAX(...)聚合器
  • 统计群组中的非NULL - 使用COUNT(...)
  • 在群组中平均生成非NULL - 使用AVG(...)

例如,如果您希望为Column2的每个值找到最小的Column3Column1的平均值,那么您的查询将如下所示:

select 
    Column1, MIN(Column2), AVG(Column3)
from 
    TableName 
group by 
    Column1