Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Изменить запрос.  [new]
mammon2012
Member

Откуда:
Сообщений: 5
DECLARE @table AS TABLE (ID INT NOT NULL IDENTITY(1, 1), a INT, b INT, c DATETIME)

INSERT INTO @table
SELECT 1,
1,
'2012-08-31'
UNION
SELECT 1,
2,
'2012-08-31'
UNION
SELECT 1,
1,
'2012-08-30'
UNION
SELECT 1,
2,
'2012-08-30'
UNION
SELECT 1,
1,
'2012-08-28'
UNION
SELECT 1,
2,
'2012-08-28'
UNION
SELECT 1,
1,
'2012-08-29'
UNION
SELECT 1,
2,
'2012-08-29'
UNION
SELECT 2,
1,
'2012-08-31'
UNION
SELECT 2,
2,
'2012-08-31'
UNION
SELECT 2,
1,
'2012-08-30'
UNION
SELECT 2,
2,
'2012-08-30'
UNION
SELECT 3,
1,
'2012-08-31'
UNION
SELECT 3,
2,
'2012-08-31'
UNION
SELECT 3,
1,
'2012-08-30'
UNION
SELECT 3,
2,
'2012-08-30'
UNION
SELECT 2,
1,
'2012-08-28'
UNION
SELECT 2,
2,
'2012-08-28'
UNION
SELECT 2,
1,
'2012-08-29'
UNION
SELECT 2,
2,
'2012-08-29'
UNION
SELECT 3,
1,
'2012-08-28'
UNION
SELECT 3,
2,
'2012-08-28'
UNION
SELECT 3,
1,
'2012-08-29'
UNION
SELECT 3,
2,
'2012-08-29'

SELECT *
FROM @table t1
JOIN (
SELECT a,
MAX(c) c
FROM @table
WHERE c BETWEEN '2012-08-28' AND '2012-08-30'
GROUP BY
a
) a
ON t1.a = a.a
AND t1.c = a.c

Можно ли выполнить такой запрос без join на одну и туже таблицу. Сервер ms-sql 2008.
31 авг 12, 10:26    [13093120]     Ответить | Цитировать Сообщить модератору
 Re: Изменить запрос.  [new]
HandKot
Member

Откуда: Sergiev Posad
Сообщений: 3058
top 1 with ties + row_number()
31 авг 12, 10:30    [13093141]     Ответить | Цитировать Сообщить модератору
 Re: Изменить запрос.  [new]
mammon2012
Member

Откуда:
Сообщений: 5
а производительность будет лучше где?
31 авг 12, 10:51    [13093256]     Ответить | Цитировать Сообщить модератору
 Re: Изменить запрос.  [new]
HandKot
Member

Откуда: Sergiev Posad
Сообщений: 3058
а все зависит от ...
31 авг 12, 10:54    [13093277]     Ответить | Цитировать Сообщить модератору
 Re: Изменить запрос.  [new]
mammon2012
Member

Откуда:
Сообщений: 5
на таблице где больше 2-3 млн записей.
Ваш вариант медленней отрабатывает. Хотелось бы скорости. Но за ваш вариант спасибо.
31 авг 12, 12:32    [13094053]     Ответить | Цитировать Сообщить модератору
 Re: Изменить запрос.  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
WITH CTE AS
(
 SELECT R=RANK()OVER(PARTITION BY a ORDER BY c DESC),*
 FROM @table
 WHERE c>='20120828' AND c<'20120831'
)
SELECT * FROM CTE WHERE R=1;
mammon2012, а разве 31-й месяц бывает?
31 авг 12, 12:49    [13094184]     Ответить | Цитировать Сообщить модератору
 Re: Изменить запрос.  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
mammon2012,

первоначальный запрос с JOINом даст задвоения в случае нескольких равных максимальных дат.
Это так и нужно?
31 авг 12, 12:57    [13094255]     Ответить | Цитировать Сообщить модератору
 Re: Изменить запрос.  [new]
mammon2012
Member

Откуда:
Сообщений: 5
mammon2012, а разве 31-й месяц бывает?
31 это число. а не месяц. там все таки datetime.


первоначальный запрос с JOINом даст задвоения в случае нескольких равных максимальных дат.
Ключ "а" и"с" уникален.
31 авг 12, 13:04    [13094336]     Ответить | Цитировать Сообщить модератору
 Re: Изменить запрос.  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31984
mammon2012
mammon2012, а разве 31-й месяц бывает?
31 это число. а не месяц. там все таки datetime.
Вы пишите константы datetime в формате '2012-08-30', а в этом случае сервер может интерпретировать 30 как день или как месяц. Лучше используйте более стабильные форматы, как использовал iap.
31 авг 12, 13:46    [13094783]     Ответить | Цитировать Сообщить модератору
 Re: Изменить запрос.  [new]
iap
Member

Откуда: Москва
Сообщений: 47145
mammon2012
iap
mammon2012, а разве 31-й месяц бывает?

31 это число. а не месяц. там все таки datetime.
Откуда это следует? Выполните SET DATEFORMAT YDM;
А потом свой запрос.
Это для типа DATE формат 'YYYY-MM-DD' всегда правильный.
Для DATETIME надо 'YYYYMMDD'
mammon2012
iap
первоначальный запрос с JOINом даст задвоения в случае нескольких равных максимальных дат.

Ключ "а" и"с" уникален.
В таком случае можно использовать ROW_NUMBER(), а не RANK()
31 авг 12, 13:46    [13094787]     Ответить | Цитировать Сообщить модератору
 Re: Изменить запрос.  [new]
HandKot
Member

Откуда: Sergiev Posad
Сообщений: 3058
mammon2012
на таблице где больше 2-3 млн записей.
Ваш вариант медленней отрабатывает. Хотелось бы скорости. Но за ваш вариант спасибо.

на больших таблицах оконные ф-ции начинают проигрывать :(

для больших таблиц джойн уже становится предпочтительней
можно еще попробовать NOT EXISTS, но подозреваю, это будет еще медленнее

и еще мысль, при небольшом количестве а сначала выбрать их, а потом подзапросом(или cross apply) вытянуть все остальное
31 авг 12, 14:14    [13095054]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить