-1

Скажу, у меня есть таблица с таким родом данных:Можно ли избежать подзапросов для такого рода запросов?

Parent Value   DateFor  ValueType 
3177 50.110000  2016-03-05 1 
3177 254390.000000 2016-03-05 2 
3177 50.110000  2016-03-06 1 
3177 254390.000000 2016-03-06 2 
3294 40.800000  2016-03-05 1 
3294 20280.000000 2016-03-05 2 

Моей таблица имеет первичный индекс Id (ID здесь не показано) и ИНОСТРАННОЕ отношение к родительской таблице, с помощью Parent колонка.

Я хотел бы, чтобы выбрать последнее значение по типу значения, для каждого родителя:

3177 50.110000  2016-03-06 1 
3177 254390.000000 2016-03-06 2 
3294 40.800000  2016-03-05 1 
3294 20280.000000 2016-03-05 2 

экспликации: Я игнорировать оба значения 2015-03-05 для родителей 3177, так как он имеет данные для 2016- 03-06. Но я беру данные с 2016-03-05 для родительского 3294, так как это последнее, что у меня есть.

Каков наиболее эффективный запрос, который бы достиг этого? Потому что у моего стола миллионы строк ...

Можно ли избежать подзапросов?

+3

'Как оптимизировать производительность для этого запроса?' Где запрос? – lad2025

+0

Какой движок базы данных? – trincot

+0

@ lad2025 У меня есть базовый 'SELECT' с фильтром где я предоставляю один родитель и не группирую, но я не знаю, как построить запрос без фильтра и с группировкой, взяв верхнюю 1 по дате, для всех данных ... – ibiza

ответ

3

Использование аналитических функций вместе с индексом покрытия должно дать вам хорошую производительность, жертвуя некоторым дисковым пространством;

CREATE INDEX ix_test 
     ON myTable([Parent], [ValueType], [DateFor] DESC) INCLUDE ([Value]); 

GO 

SELECT [Parent], [Value], [DateFor], [ValueType] 
FROM (
    SELECT *, ROW_NUMBER() 
      OVER (PARTITION BY [Parent], [ValueType] ORDER BY [DateFor] DESC) rn 
    FROM myTable 
) z 
WHERE rn=1; 
+0

Спасибо, это отлично! Вопрос: Почему 'INCLUDE ([Value])' вместо того, чтобы помещать '[Value]' в самом индексе (с другими столбцами в разделе 'ON')? – ibiza

+1

@ibiza Здесь вы можете использовать либо: 'INCLUDE', как правило, сохраняет некоторое пространство. Для более подробной информации вы можете, например, посмотреть [здесь] (https://msdn.microsoft.com/en-us/library/ms190806 (v = sql.120) .aspx). –

1

Вопрос слишком широк, поэтому ответ является своего рода родовым. Используйте SQL Query w/sub-query или Temp Table (последнее может привести к повышению производительности). Сначала получите самую раннюю дату (минимальное значение) на SELECT MAX(DateFor) as MinDate FROM [YourTable] Group BY [Parent], [ValueType], затем запустите второй оператор SELECT, используя MinDate в статье WHERE. Надеюсь, это поможет.

1

Другой метод, который может также иметь хорошую производительность является:

SELECT [Parent], [Value], [DateFor], [ValueType] 
FROM t 
WHERE DateFor = (SELECT MAX(t2.DateFor) 
       FROM t t2 
       WHERE t2.Parent = t.Parent AND t2.ValueType = t.ValueType 
       ); 

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

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