2016-10-18 3 views
1

У нас есть стол.Как найти максимум в таблице

ID  |department_ID|mod_date 
--------------------------------- 
A  | 33   | 12/03/2014 
A  | 44   | 23/04/2015 
A  | 55   | 20/05/2016 
B  | 44   | 26/01/2014 
B  | 33   | 24/02/2015 
B  | 12   | 24/12/2015 
B  | 55   | 12/02/2016 
C  | 13   | 22/05/2014 
C  | 14   | 01/05/2015 
C  | 55   | 02/07/2016 
C  | 14   | 03/08/2016 
C  | 55   | 05/10/2016 

Из этой таблицы мы должны извлечь тот ID, где department_id является 55 но был изменен после того, как 12/10/15 ни к чему, кроме 55.

Помогите с запросом, поскольку мне нужно сделать это для огромного количества данных.

+0

Что изменилось и какое действие нужно сделать? –

+0

должно быть отслеживание предыдущего идентификатора деления, чтобы мы могли идентифицировать, если предыдущее значение равно 55 или нет. – Sherlock

+0

. Дайте образец вывода на основе вашего примера ввода, а также того, что вы пробовали до сих пор, и объясните, как он не дает ожидаемых результатов – Dijkgraaf

ответ

1

Вы можете добиться этого с помощью подзапроса:

CREATE TABLE #0 (ID varchar(100), department_ID int, mod_date date) 

SET DATEFORMAT DMY 

INSERT #0 VALUES 
('A',33,'12/03/2014'),('A',44,'23/04/2015'),('A',55,'20/05/2016') 
,('B',44,'26/01/2014'),('B',33,'24/02/2015'),('B',12,'24/12/2015') 
,('B',55,'12/02/2016'),('C',13,'22/05/2014'),('C',14,'01/05/2015') 
,('C',55,'02/07/2016'),('C',14,'03/08/2016'),('C',55,'05/10/2016'); 

SELECT DISTINCT latest.ID 
FROM 
(
    SELECT ID, mod_date = MAX(mod_date) 
    FROM #0 
    GROUP BY ID 
) maximum 
JOIN #0 latest 
    ON latest.ID = maximum.ID 
    AND latest.mod_date = maximum.mod_date 
JOIN #0 older 
    ON older.ID = latest.ID 
    AND older.mod_date < latest.mod_date 
    AND (older.department_ID <> latest.department_ID OR older.department_ID IS NULL) 
WHERE latest.department_ID = 55 
    AND older.mod_date > '2015-10-12' 
+0

Привет, Спасибо за ваш ответ .. можем ли мы добавить что-то к этому запросу так, чтобы оно дало и последнее преобразование. Я имею в виду для – SYMA

+0

за A 44 23/04/2015 – SYMA

+0

Для A Я должен получить две записи с дептом id 44 и 55, а для B тоже то же самое. Извините за несколько комментариев, которые были по ошибке. – SYMA

1

Если правильно понял, то вы можете искать это скрипт

SELECT ID 
FROM TableName 
WHERE department_ID = 55 AND mod_date > '<your_date>' 
GROUP BY ID 
Having COUNT(department_ID) = 1 
+0

Могу ли я получить последний переход. Я имею в виду, для A ID мне нужны две записи с идентификатором 55 и 44, а также для B ID, а также – SYMA

+0

, и у меня нет mod_date. Это должно быть максимальным из них. Group by item id – SYMA

+0

Не уверен в требованиях к вашему бизнесу, но если вы ищете два отдела, вы можете использовать предложение IN 'department_ID IN (55,44)' –

0

возможно это?

declare @temp table (id varchar(1), department_id int, mod_Date date) 

insert into @temp values ('A', 33, '20140312') 
insert into @temp values ('A', 44, '20150423') 
insert into @temp values ('A', 55, '20160520') 
insert into @temp values ('B', 44, '20140126') 
insert into @temp values ('B', 33, '20150224') 
insert into @temp values ('B', 12, '20151224') 
insert into @temp values ('B', 55, '20160212') 
insert into @temp values ('C', 13, '20140522') 
insert into @temp values ('C', 14, '20150501') 
insert into @temp values ('C', 55, '20160702') 
insert into @temp values ('C', 14, '20160803') 
insert into @temp values ('C', 55, '20161005') 

select id, max(mod_Date) as lastchanged 
from @temp 
where department_id = 55 
and mod_date > '20151012' 
group by id 
having count(department_id) = 1 

возвращается:

id lastchanged 
A 2016-05-20 
B 2016-02-12 
0

Сортировать по дате: -

SELECT * FROM table WHERE mod_date > '2015/10/12' AND 
department_ID=55 ORDER BY mod_date DESC Limit 1; 

Сортировать по ID: -

SELECT * FROM table WHERE mod_date > '2015/10/12' AND 
department_ID=55 ORDER BY ID Limit 1; 
0

Вы можете сделать это с помощью ROW_NUMBER() дважды. Добавление следующие два столбца с вашими данными:

SELECT ID, 
     Department_ID, 
     mod_date, 
     RowNum = ROW_NUMBER() OVER(PARTITION BY ID ORDER BY mod_date DESC), 
     RowNum2 = ROW_NUMBER() OVER(PARTITION BY ID, Department_ID ORDER BY mod_date) 
FROM #T 
WHERE mod_Date > '20151012'; 

дает

ID Department_ID mod_date RowNum RowNum2 
-------------------------------------------------- 
A 55    2016-05-20 1  1 
B 12    2015-12-24 2  1 
B 55    2016-02-12 1  1 
C 14    2016-08-03 2  1 
C 55    2016-07-02 3  1 
C 55    2016-10-05 1  2 

Поскольку вы заинтересованы только в том, где в настоящее время отдел ИД 55, вам нужно фильтровать для RowNum = 1 AND Department_ID = 55, который выходит:

ID Department_ID mod_date RowNum RowNum2 
-------------------------------------------------- 
A 55    2016-05-20 1  1 
B 55    2016-02-12 1  1 
C 55    2016-10-05 1  2 

Обратите внимание, что RowNum2 для ID = C равно 2, поскольку это второй раз за период, когда C было 55, вы являетесь заинтересованы в том, где идентификатор ранее не был изменен на 55, так что вам нужно еще предикат RowNum2 = 1 дает окончательный запрос о:

SELECT ID, 
     Department_ID, 
     mod_date 
FROM ( SELECT ID, 
        Department_ID, 
        mod_date, 
        RowNum = ROW_NUMBER() OVER(PARTITION BY ID ORDER BY mod_date DESC), 
        RowNum2 = ROW_NUMBER() OVER(PARTITION BY ID, Department_ID ORDER BY mod_date) 
      FROM #T 
      WHERE mod_Date > '20151012' 
     ) AS t 
WHERE Department_ID = 55 
AND  RowNum = 1  -- CURRENT RECORD 
AND  RowNum2 = 1; -- FIRST TIME ID HAS BEEN THIS DEPARTMENT 

полный рабочий DEMO

CREATE TABLE #T (ID CHAR(1), Department_ID INT, mod_date DATE); 
INSERT #T 
VALUES 
    ('A', 33, '20140312'), 
    ('A', 44, '20150423'), 
    ('A', 55, '20160520'), 
    ('B', 44, '20140126'), 
    ('B', 33, '20150224'), 
    ('B', 12, '20151224'), 
    ('B', 55, '20160212'), 
    ('C', 13, '20140522'), 
    ('C', 14, '20150501'), 
    ('C', 55, '20160702'), 
    ('C', 14, '20160803'), 
    ('C', 55, '20161005'); 

SELECT ID, 
     Department_ID, 
     mod_date 
FROM ( SELECT ID, 
        Department_ID, 
        mod_date, 
        RowNum = ROW_NUMBER() OVER(PARTITION BY ID ORDER BY mod_date DESC), 
        RowNum2 = ROW_NUMBER() OVER(PARTITION BY ID, Department_ID ORDER BY mod_date) 
      FROM #T 
      WHERE mod_Date > '20151012' 
     ) AS t 
WHERE Department_ID = 55 
AND  RowNum = 1  -- CURRENT RECORD 
AND  RowNum2 = 1; -- FIRST TIME ID HAS BEEN THIS DEPARTMENT 

РЕЗУЛЬТАТЫ

ID Department_ID mod_date 
---------------------------------- 
A 55    2016-05-20 
B 55    2016-02-12