2016-11-11 2 views
1

У меня есть сценарий, чтобы получить соответствующее значение поля «Макс» и запись «Min» Вы можете найти выборочные данные нижеMax и минимальное значения в

----------------------------------------------------------------------- 
ID    Label    ProcessedDate 
----------------------------------------------------------------------- 
1    Label1   11/01/2016 
2    Label2   11/02/2016 
3    Label3   11/03/2016 
4    Label4   11/04/2016 
5    Label5   11/05/2016 

у меня есть поле «ID» населенное в другой таблице в качестве внешнего ключа. При запросе этих записей в этой таблице на основе поля «ID» мне нужно получить поле «Ярлык» с обработанной датой «Макс» и «Мин» обработанной датой.

----------------------------------------------------------------------- 
    ID  LabelID  GroupingField 
----------------------------------------------------------------------- 
    1  1   101 
    2  2   101 
    3  3   101 
    4  4   101 
    5  5   101 
    6  1   102 
    7  2   102 
    8  3   102 
    9  4   102 

И окончательный результат Я ожидаю, что он будет выглядеть примерно так.

----------------------------------------------------------------------- 
    GroupingField   FirstProcessed   LastProcessed 
----------------------------------------------------------------------- 
    101     Label1     Label5 
    102     Label1     Label4 

У меня «почти» удалось получить этот результат выше, используя функцию ранга, но все еще не удовлетворив его. Поэтому я ищу, если кто-то может предоставить мне лучший вариант.

Спасибо, Prakazz

ответ

1

Вы можете использовать функцию SQL row_number() с помощью раздела К следующему сочетанию Группировать

;with cte as (
    select 
     t.Label, t.ProcessedDate, 
     g.GroupingField, 
     ROW_NUMBER() over (partition by GroupingField Order By ProcessedDate ASC) minD, 
     ROW_NUMBER() over (partition by GroupingField Order By ProcessedDate DESC) maxD 

    from tbl t 
    inner join GroupingFieldTbl g 
    on t.ID = g.LabelID 
) 
select GroupingField, max(FirstProcessed) FirstProcessed, max(LastProcessed) LastProcessed 
from (
select 
    GroupingField, 
    FirstProcessed = CASE when minD = 1 then Label else null end, 
    LastProcessed = CASE when maxD = 1 then Label else null end 
from cte 
where 
    minD = 1 or maxD = 1 
) t 
group by GroupingField 
order by GroupingField 

Я также использовал выражения CTE сделать кодирования проще и понятным

Выход в

enter image description here

+0

Да, это выглядит отлично! У меня было почти то же самое, что только отсутствующая вещь заключалась в том, что я не использовал CTE и еще один дополнительный слой группировки с groupingID. Во всяком случае спасибо за это! – Prakazz

3
CREATE TABLE #Details (ID INT,LabelID INT,GroupingField INT) 
CREATE TABLE #Details1 (ID INT,Label VARCHAR(100),ProcessedDate VARCHAR(100)) 

INSERT INTO #Details1 (ID ,Label ,ProcessedDate) 
SELECT 1,'Label1','11/01/2016' UNION ALL 
SELECT 2,'Label2','11/02/2016' UNION ALL 
SELECT 3,'Label3','11/03/2016' UNION ALL 
SELECT 4,'Label4','11/04/2016' UNION ALL 
SELECT 5,'Label5','11/05/2016' 


INSERT INTO #Details (ID ,LabelID ,GroupingField) 
SELECT 1,1,101 UNION ALL 
SELECT 2,2,101 UNION ALL 
SELECT 3,3,101 UNION ALL 
SELECT 4,4,101 UNION ALL 
SELECT 5,5,101 UNION ALL 
SELECT 6,1,102 UNION ALL 
SELECT 7,2,102 UNION ALL 
SELECT 8,3,102 UNION ALL 
SELECT 9,4,102 

;WITH CTE (GroupingField , MAXId ,MinId) AS 
(
    SELECT GroupingField,MAX(LabelID) MAXId,MIN(LabelID) MinId 
    FROM #Details 
    GROUP BY GroupingField 
) 


SELECT GroupingField ,B.Label FirstProcessed, A.Label LastProcessed 
FROM CTE 
JOIN #Details1 A ON MAXId = A.ID 
JOIN #Details1 B ON MinId = B.ID