2013-09-17 2 views
2

У меня есть таблица, как этотКак max (date) и использовать функцию in в sql-сервере в одном запросе?

id color shade date 
--- ---- ----- ----- 
1 red dark 01/01/1990 
2 red light 09/16/2013 
3 green light 08/15/2010 
4 green dark 09/18/2012 
5 maroon dark 08/20/2013 
6 white dark 08/31/2013 
7 white light 08/30/2012 
8 purple light 08/20/2010 

Я хотел записи для каждого цвета с последней датой. Так что я попытался сделать:

select id, color, shade, max(date) from mytable; 

Это не сработало, и дал мне ошибку:

is invalid in the select list because it is not contained in either an aggregate 
function or the GROUP BY clause. 

Alright, поэтому я добавил его в Group By, как это было предложено ошибки

select id, color, shade, max(date) from mutable 
Group by id, color, shade 

Это дало мне желаемые результаты.

Вопрос

Теперь я хотел тот же запрос, как описано выше, повторяется только для определенных цветов. Например, я только хотел увидеть красные и зеленые.

Так что я сделал:

select id, color, shade, max(date) from mutable 
Where color in ('red', 'green') 
Group by id, color, shade; 

Однако это не дает мне правильное число результатов, потому что я предполагаю, что они группируются по shade.

Каков наилучший способ получить мои желаемые результаты? В основном я хочу, чтобы max date из двух экземпляров одной и той же вещи, и в дальнейшем из таблицы нужны только определенные цвета.

+0

, когда вы говорите одно и то же, вы имеете в виду тот же цвет? И ваш желаемый результат: «1, красный, свет, 09/16/2013» и «4, зеленый, темный, 09/18/2012»? – Elmer

ответ

1
select id, color, shade, max(date) over() AS m_date from mutable 

OVER ПУНКТА, используемые в анализировать функции

+0

Что делает 'over()' достижение? – birdy

+0

, если ваша версия SQL SERVER> = 2005 U может использовать предложение OVER) – realnumber3012

2

В стандартном SQL любой из следующих запросов решить проблему:

Вариант 1

SELECT t1.* FROM t t1 
LEFT JOIN t t2 
ON t1.color = t2.color AND t1.shade = t2.shade AND t1.date < t2.date 
WHERE t2.date IS NULL 

Вариант 2

SELECT t1.* FROM t t1 
JOIN (
    SELECT color, shade, max(date) date FROM t 
    GROUP BY color, shade 
) t2 
ON t1.color = t2.color AND t1.shade = t2.shade AND t1.date = t2.date 

В ваших данных примера все результаты должны быть возвращены, поэтому на нем нет смысла работать. Я немного изменил его в этом:

| ID | COLOR | SHADE |  DATE | 
|----|-------|-------|------------| 
| 1 | red | dark | 1990-01-01 | 
| 2 | red | dark | 2013-09-16 | 
| 3 | green | light | 2010-08-15 | 
| 4 | green | dark | 2012-09-18 | 
| 5 | green | dark | 2013-08-20 | 
| 6 | white | dark | 2013-08-31 | 
| 7 | white | light | 2012-08-30 | 
| 8 | white | light | 2010-08-20 | 

Выход из запросов будет:

| ID | COLOR | SHADE |  DATE | 
|----|-------|-------|------------| 
| 2 | red | dark | 2013-09-16 | 
| 3 | green | light | 2010-08-15 | 
| 5 | green | dark | 2013-08-20 | 
| 6 | white | dark | 2013-08-31 | 
| 7 | white | light | 2012-08-30 | 

Убедитесь, что вы применить соответствующие упорядоченности.

Fiddle here.

1

Простой способ думать о том, что это сначала создать запрос, который дает вам последнюю дату для каждого цвета:

select color, max([date]) as maxdate 
from mytable 
group by color; 

Затем путем присоединения этого запроса с помощью простого запроса на выборку, который просто извлекает все строки из исходная таблица:

select t.[id], t.color, t.shade, sq.maxdate 
from mytable as t 
inner join (
    select color, max([date]) as maxdate 
    from mytable 
    group by color 
) as sq 
on (t.color = sq.color); 

Затем, чтобы ограничить результаты только определенные цвета, просто добавьте в вашем предложении where в конце запроса:

where color in ('red', 'green'); 
0

Самый простой способ сделать это с помощью функций окна/ранжирования. Вот пример с row_number():

select id, color, shade, "date" 
from (select t.*, 
      row_number() over (partition by color order by "date" desc) as seqnum 
     from mytable 
    ) t 
where seqnum = 1; 
2

Попробуйте

SELECT t1.* FROM t t1 
JOIN 
(
    SELECT color, MAX([date]) [date] FROM t 
    WHERE color IN ('red', 'green') 
    GROUP BY color 
) t2 
ON t1.color = t2.color AND t1.date = t2.date 
ORDER BY ID 

ВЫВОД

id color shade date 
2 red  light 2013-09-16 
5 green dark 2013-08-20 

ИЛИ

SELECT id, color, shade, [date] 
FROM 
(
    SELECT *, 
     row_number() OVER (PARTITION BY color ORDER BY [date] DESC) AS sno 
    FROM t 
    WHERE color IN ('red', 'green') 
) tt 
WHERE sno = 1 
ORDER BY ID 

OUTPUT

id color shade date 
2 red  light 2013-09-16 
5 green dark 2013-08-20 

ИЛИ

SELECT id, color, shade, [date] 
FROM 
(
    SELECT *, 
     MAX([date]) OVER (PARTITION BY color) AS maxdate 
    FROM t 
    WHERE color IN ('red', 'green') 
) tt 
WHERE [date] = maxdate 
ORDER BY ID 

ВЫВОД

id color shade date 
2 red  light 2013-09-16 
5 green dark 2013-08-20 
Смежные вопросы