2010-10-29 5 views
5

У меня есть таблица, какКак получить несколько самых высоких значений из таблицы?

id f1 
-------------- 
1 2000-01-01 
1 2001-01-01 
1 2002-01-01 
1 2003-01-01 

И я хочу, чтобы сказать последние 3 даты в одном ряду

CREATE TABLE Test 
(
    id INT NOT NULL, 
    f1 DATETIME NOT NULL, 
) 

INSERT INTO Test (id, f1) VALUES (1, '1/1/2000') 
INSERT INTO Test (id, f1) VALUES (1, '1/1/2001') 
INSERT INTO Test (id, f1) VALUES (1, '1/1/2002') 
INSERT INTO Test (id, f1) VALUES (1, '1/1/2003') 

SELECT T1.* FROM Test as T1 

пытался что-то вроде

  SELECT T1.*,T2.* 
      FROM Test AS T1 
LEFT OUTER JOIN Test AS T2 ON T1.id = T2.id AND (T2.f1 > T1.f1) 
+3

Почему это должно быть все в одной строке? Было бы намного проще иметь только один столбец. –

+1

Я думаю, что более разумно возвращать их в виде строк, а не 1 строку с несколькими столбцами. – dotariel

+0

Вам нужны три последних даты для каждого идентификатора? (Я заметил, что ваш идентификатор всегда 1) –

ответ

3

В SQL Server вы можете сделать select top 3 * from Test order by f1 desc. Другой СУБД имеют аналогичные, такие как максимальные возможности для MySQL limit, Oracle, rownum и т.д.

+0

Это не сработает. Это дало бы последние 3 даты в одной колонке. Maestro1024 запрашивает последние 3 даты в одной строке. – pavanred

3

Хотя я не вы можете начать с:

SELECT * FROM Test ORDER BY f1 DESC LIMIT 3 

Это должно дать вам результат, как:

id f1 
1 2003-01-01 
1 2002-01-01 
1 2001-01-01 

Ввод их в один ряд, хотя, может быть немного сложнее ...

2

Вы можете сделать это с помощью комбинации ORDER BY, TOP и PIVOT, по крайней мере, на SQL Server. Похоже, что многие другие ответы игнорировали необходимость того, чтобы результат был «все в одной строке».

0

Вы можете получить первые 3 даты подряд, повернув стол и, возможно, соединяя даты, если вы хотите, чтобы они были в одном столбце после поворота.

Редактировать: вот запрос для поворота таблицы и предоставления последних 3 дат подряд. Но для поворота вам понадобятся данные, доступные в таблице. Я понял, что, поскольку мы запрашиваем последние 3 даты, мы не будем знать точные значения, которые можно было бы развернуть вокруг столбца даты. Итак, во-первых, я запросил последние 3 даты в таблице temp. Затем запустили опорную точку в row_number 1, 2 и 3, чтобы получить последние 3 даты подряд.

Select Top 3 * into #Temp from Test order by f1 desc 

Теперь стержень на колонке row_number -

SELECT id,[3] as Latest,[2] as LatestMinus1,[1] as LatestMinus2 
FROM (
select ROW_NUMBER() OVER(ORDER BY f1) AS RowId,f1,id from #Temp) AS Src 
PIVOT (Max(f1) FOR RowId IN ([1],[2],[3])) AS pvt 

В результате -

Id | Latest     |LatestMinus1    |LatestMinus2 
1 | 2003-01-01 00:00:00.000 | 2002-01-01 00:00:00.000 | 2001-01-01 00:00:00.000 

И, конечно

drop table #Temp 
+0

Редактировать: добавлен запрос к моему ответу. – pavanred

+0

Аналитика не поддерживается всеми базами данных - SQL Server 2005+, Oracle 9i +, PostgreSQL 8.4 + ... но не MySQL –

0

что по этому поводу?

SELECT T1.f1 as "date 1", T2.f1 as "date 2", T3.f1 as "date 3" 
    FROM (SELECT * 
     FROM `date_test` 
     ORDER BY `f1` DESC 
     LIMIT 1) AS T1, 
     (SELECT * 
     FROM `date_test` 
     ORDER BY `f1` DESC 
     LIMIT 1, 1) AS T2, 
     (SELECT * 
     FROM `date_test` 
     ORDER BY `f1` DESC 
     LIMIT 2, 1) AS T3 
; 

Какие выходы:

+------------+------------+------------+ 
| date 1  | date 2  | date 3  | 
+------------+------------+------------+ 
| 2003-01-01 | 2002-01-01 | 2001-01-01 | 
+------------+------------+------------+ 

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

Используя JOIN, вы можете сделать это :

SELECT T1.id, 
     T1.f1 as "date 1", 
     T2.f1 as "date 2", 
     T3.f1 as "date 3" 
    FROM `date_test` as T1 
    LEFT JOIN (SELECT * FROM `date_test` ORDER BY `f1` DESC) as T2 ON (T1.id=T2.id AND T1.f1 != T2.f1) 
    LEFT JOIN (SELECT * FROM `date_test` ORDER BY `f1` DESC) as T3 ON (T1.id=T3.id AND T2.f1 != T3.f1 AND T1.f1 != T3.f1) 
GROUP BY T1.id 
ORDER BY T1.id ASC, T1.f1 DESC 

Что вернет что-то вроде:

+----+------------+------------+------------+ 
| id | date 1  | date 2  | date 3  | 
+----+------------+------------+------------+ 
| 1 | 2001-01-01 | 2003-01-01 | 2002-01-01 | 
+----+------------+------------+------------+ 

Недостатком является то, что date1, date 2 и date 3 не обязательно будут в определенном порядке (в соответствии с приведенным выше примером вывода). Но это может быть достигнуто программно. Плюсом является то, что вы можете вставить предложение WHERE до GROUP BY, и вы можете искать, например, T1.id.

1

в T-SQL (Это поможет вам первые три даты, даже если они все же значение)

with TestWithRowNums(f1, row_num) as 
(
select f1, row_number() over(order by [f1] desc) as row_num from test 
) 
select 
(select [f1] from TestWithRowNums where row_num = 1) as [Day 1], 
(select [f1] from TestWithRowNums where row_num = 2) as [Day 2], 
(select [f1] from TestWithRowNums where row_num = 3) as [Day 3] 

Это поможет вам в тройку отчетливые даты

with TestWithRankNums(f1, rank_num) as 
(
select f1, dense_rank() over(order by [f1] desc) as rank_num from test 
) 
select 
(select top 1 [f1] from TestWithRankNums where rank_num = 1) as [Day 1], 
(select top 1 [f1] from TestWithRankNums where rank_num = 2) as [Day 2], 
(select top 1 [f1] from TestWithRankNums where rank_num = 3) as [Day 3] 

Try это в SQL Server 2005

--to get top three values even if they are the same 
select [1] as Day1, [2] as Day2, [3] as Day3 from 
(select top 3 f1, row_number() over(order by [f1] desc) as row_num from test) src 
pivot 
(
max(f1) for row_num in([1], [2], [3]) 
) as pvt 
--to get top three distinct values 
select [1] as Day1, [2] as Day2, [3] as Day3 from 
(select f1, dense_rank() over(order by [f1] desc) as row_num from test) src 
pivot 
(
max(f1) for row_num in([1], [2], [3]) 
) as pvt 
+0

Я использую MS SQL, и это не работает. Является ли синтаксис правильным или просто недействительным в MS SQL? – Maestro1024

+0

@ Maestro1024, это будет работать только в новых версиях SQl Server, но, безусловно, передает проверку синтаксиса. – HLGEM

+0

@ Maestro1024, какую версию MS SQL Server вы используете? –

Смежные вопросы