2013-12-19 3 views
1

Я пытаюсь выбрать строки из таблицы базы данных Microsoft SQL Server, которые для каждого идентификатора в одном столбце (идентификатор) выбирают только строки, у которых есть другой столбца как максимальный (IDtoBeMaxed). Например:Выберите строки из таблицы базы данных SQL Server, только строки, которые имеют другой столбец как максимальный

Из этой таблицы

ID SomeValue IDtoBeMaxed 
    1 56  2 
    1 59  2 
    1 80  1 
    2 55  5 
    2 80  5 
    2 56  3 
    2 81  3 

Я только хочу

ID SomeValue IDtoBeMaxed 
    1 56  2 
    1 59  2 
    2 55  5 
    2 80  5 

У меня есть этот запрос, который работает, но я думаю, что должно быть более быстрым способом, который уменьшает время отклика запрос. Итак, этот запрос дает мне то, что я хочу, я ищу более быстрый запрос времени ответа.

SELECT * 
FROM myTable 
WHERE ID = 2 
    AND IDtoBeMaxed = (SELECT MAX(IDtoBeMaxed) FROM myTable WHERE ID = 2) 

Редакции: Мне не нужны все строки, как я показал в приведенном выше примере. Мне нужны только строки для определенного идентификатора, как и запрос, который я написал сам.

Результаты: Я попробовал запрос Shavkat, но это не быстрее, чем запрос, который я написал. Остальные ответы возвращают все строки, которые я не ищу. Так что это все еще обсуждается. Но спасибо за ваши ответы.

+0

Запрошенный вами запрос не возвращает нужные значения. Вы уверены, что это правильно? Запрос никогда не вернет строку с идентификатором 1. http://sqlfiddle.com/#!6/d3732/1/0 – SteveB

ответ

2

Вы пытаетесь вернуть все строки из таблицы в один запрос? Что-то вроде следующего будет работать:

SELECT t.Id,t.SomeValue,t.IDtoBeMaxed 
FROM MyTable t 
JOIN (
    SELECT Id,MAX(IDToBeMaxed) AS MaxId 
    FROM MyTable 
    GROUP BY Id 
) AS m ON t.Id=m.Id AND t.IDToBeMaxed=m.MaxId 

В ответ на ваши изменения:

Запрос вы написали примерно так же просто, как вы можете получить. Если вам нужно улучшить время отклика, вы должны посмотреть на создание индекса на столбцах ID и IDToBeMaxed.

CREATE INDEX ix_IDMaxed ON MyTable(ID,IDToBeMaxed) 

Это вариант для вас?

+0

См. Мои правки. – Dogahe

+0

Я должен попытаться увидеть, если это быстрее. Дам вам знать. Благодарю. – Dogahe

+0

Этот запрос велик, пока данные просто такие. Если вы добавите строку, она работает неправильно. INSERT INTO mytable ЗНАЧЕНИЯ (3, 54, 6) Посмотрите здесь http://sqlfiddle.com/#!6/d71e6/1/0 – SteveB

0

Не могли бы вы, пожалуйста, попробуйте ниже ...

WITH selectOne 
      AS (SELECT ROW_NUMBER() OVER (PARTITION BY SomeValue, ID ORDER BY IDtoBeMaxed DESC) AS RowNum , 
         ID , 
         SomeValue , 
         IDtoBeMaxed 
       FROM  myTable 
      ) 
    SELECT * 
    FROM selectOne 
    WHERE RowNum = 1 
1

Вот старая школа первая:

declare @myTable table (ID int, SomeValue int, IDtoBeMaxed int) 
insert into @myTable 
values 
    (1, 56,  2), 
    (1, 59,  2), 
    (1, 80,  1), 
    (2, 55,  5), 
    (2, 80,  5), 
    (2, 56,  3), 
    (2, 81,  3), 
    (3, 55,  5), 
    (3, 80,  5), 
    (3, 56,  5), 
    (3, 81,  5) 

select a.* 
from @myTable a left join @myTable b 
on a.ID = b.ID and a.IDtoBeMaxed < b.IDtoBeMaxed 
where b.ID is null and a.ID = 2 
0

Следующий пример возвращает записи, ранжированных по их IDtoBeMaxed

;WITH cte AS 
(SELECT *, DENSE_RANK() OVER(PARTITION BY ID ORDER BY IDtoBeMaxed DESC) AS dr 
    FROM myTable 
) 
    SELECT * 
    FROM cte 
    WHERE dr = 1 

Демо на SQLFiddle

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