2015-07-22 3 views
-9

Следующий запрос возвращает 550 записей, которые я затем группирую по некоторым столбцам в контроллере через linq. Однако, как я могу достичь логики «group by» в самом SQL-запросе? Кроме того, после группировки, мне нужно показать только 150 результатов для пользователя.Как использовать группу только для некоторых столбцов в sql-запросе?

Текущий запрос 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

Что вы пытаетесь сделать здесь действительно? Не могли бы вы предоставить образцы данных и ожидаемый результат? –

+6

Покажите нам пример того, что вы ищете. Если у вас есть две разные строки с Column1 = 'A', но разные значения для столбцов 2 и 3, что должно быть возвращено? – RBarryYoung

+1

@vignesh: Чего вы хотите достичь? Можете ли вы поделиться информацией и результатами поиска? Вам нужно будет иметь некоторую совокупную функцию, а также использовать группу по –

ответ

0

Я предполагаю, что вы хотите Группировать колонке 1, но включают столбцы 2 и 3 в ваш Выбрать. Использование группы Вы не можете этого сделать. Однако вы можете сделать это, используя функцию T-SQL Windowing с помощью оператора OVER(). Поскольку вы не говорите, как хотите объединиться, я не могу привести пример. Но посмотрите на функции T-SQL Windowing. Это article может помочь вам приступить к работе.

0

Одна важная вещь, которую вам нужно знать о GROUP BY, заключается в том, что вы должны предположить, что в каждом столбце вне списка имеется несколько значений. В вашем случае вы должны предположить, что для каждого значения Column1 было бы несколько значений Column2 и Column3, которые рассматриваются как одна группа.

Если вы хотите, чтобы ваш запрос обрабатывал любой из этих столбцов, вы должны указать, что делать с этими несколькими значениями.

Вот некоторые варианты у вас есть:

  • Выберите наименьшее или наибольшее значение для столбца в группе - использовать MIN(...) или MAX(...) агрегатор для этого
  • графа Непро- NULL элементов в a - использовать COUNT(...)
  • Производить среднее значение не NULL значений в группе - использовать AVG(...)

Например, если вы хотели бы найти наименьшее Column2 и в среднем Column3 для каждого значения Column1, ваш запрос будет выглядеть следующим образом:

select 
    Column1, MIN(Column2), AVG(Column3) 
from 
    TableName 
group by 
    Column1 
Смежные вопросы