2016-07-15 11 views
1

У меня есть фотографии в базе данных, которые мне теперь нужно извлечь. Столбец изображения имеет тип varbinary(max).T-SQL извлечение изображения из Max (Дата)

Я попробовал несколько примеров, используя JOIN или подзапрос, безрезультатно. Разработанный запрос будет работать, если бы не изображение. Использование DISTINCT и MAX(date) по-прежнему не может устранить старое изображение. Многие идентификаторы имеют несколько изображений. Используя Max(Date), вы получите самую последнюю дату, но добавление в изображение исключает всю фильтрацию.

Запрос выглядит следующим образом:

SELECT DISTINCT ID, Image, DateModified, GETDate() 
FROM images 
WHERE 
    TYPE = 'B' 

ID Image DateMod  Type 

1 0x789 01-02-2014 B 

1 0x791 11-12-2015 B <-- this is a tgt record 

2 0x675 12-01-2015 A 

5 0x324 06-26-2015 B <-- this is a tgt record 

Если я использую MAX(DateModified), что заставляет GROUP BY и до сих пор не устраняет старые изображения. Мне нужен новый тип «B» для каждого ID. Я работаю на SQL Server 2012.

Что мне нужно для выходных image, ID, DateModified, TodaysDate (GetDate)

+0

что ваши критерии для записи TGT. это определенный период времени или верхние русские записи? – H20rider

+0

@ H20rider «Новейшее изображение типа« B »для каждого идентификатора» - т. Е.«ТОП-1» в порядке даты для каждой группы (по id) и где Тип = B. –

+0

@ Давай посмотрим на мой ответ. Вы не используете 'GROUP BY', хотя предложение' DISTINCT' может эмулировать его при правильном использовании. –

ответ

4

Довольно, что вы хотите что-то вроде этого.

with SortedResults as 
(
    select ID 
     , Image 
     , DateMod 
     , Type 
     , ROW_NUMBER() over (partition by ID order by DateMod desc) as RowNum 
    from images 
    where Type = 'B' 
) 


select ID 
    , Image 
    , DateMod 
    , GetDate() 
from SortedResults 
where RowNum = 1 
+0

@ Sean.Lange Пришло смешное, ваш запрос к SQL Analyzer использовал на 5% меньше, хотя я отчетливо помню, как первый раз я запустил запрос, что ваш запрос занял полтора секунды дольше, чтобы появиться в результатах. Я провел некоторое исследование этого феномена и нашел очень хорошо написанную статью (http://guyharrison.squarespace.com/blog/2009/6/4/partition-by-versus-group-by.html) об аналитическом функций против GROUP BY. первый заканчивает забивание CPU и затрат на память, хотя IO понижен (только одно сканирование чтения таблицы). Эта статья увлекательна и бросает вызов моему первоначальному восприятию. :) –

+0

@clifton_h - Еще интереснее то, что книга посвящена Oracle, поэтому любой анализ производительности здесь не уместен, потому что вы используете SQL-сервер. –

+0

Шон, спасибо за решение. Он извлекает записи, которые я ищу. Я также попробовал решение ниже, и он выпустил еще 9 записей. Поэтому я сейчас смотрю на разницу. Мне нравится подход CTE, разбивающий записи. Хорошая работа. – Dave

2

Попробуйте следующий запрос

SELECT 
    I.[Image], 
    I.DateMod, 
    GetDate() 
FROM 
(
    SELECT 
     ID, 
     MAX(DateModified) AS DateModified 
    FROM 
     images 
    WHERE 
     [TYPE] = 'B' 
    GROUP BY 
     ID 
) A INNER JOIN 
images I ON A.ID = I.ID AND A.DateModified = I.DateModified 
+0

Этот запрос дает количество записей, которые я ожидал от своих испытаний на прошлой неделе. Решение выше от Шона также является хорошим решением. Однако это привело к сокращению на 9 записей. Анализируя это в настоящее время. Оба решения предоставляют результаты, которые мне нужны. Просто нужно определить, нужны ли эти 9 записей или нет. Спасибо вам за помощь. – Dave

0

Проблема, скорее всего, в два раза:

  • 1) Вы путаете логический порядок пунктов, используемых в SQL Server.
  • 2) Ваш преступник DISTINCT.

Предлагаю вам изучить и запомнить Logical order of SQL Clauses, чтобы вы поняли логически, как SQL Server читает ваш предписанный запрос. Для простоты начинайте с списка Classic, который используется во многих местах.

Classic   Complete 

FROM  | FROM 
WHERE  | ON 
GROUP BY | JOIN 
HAVING  | WHERE 
SELECT  | GROUP BY 
ORDER BY | WITH CUBE, WITH ROLLUP 
      | HAVING 
      | SELECT 
      | DISTINCT 
      | ORDER BY 
      | TOP 

Уже сейчас мы можем понять, почему ваш запрос возвращает результаты неправильно, так как SQL Server является не разбив колонну наборов вместе, а разбив различные строки по столбцам.

Ваш пример списка:

ID Image DateMod  Type 

1 0x789 01-02-2014 B  
1 0x791 11-12-2015 B <-- this is a tgt record 
2 0x675 12-01-2015 A  
5 0x324 06-26-2015 B <-- this is a tgt record 

Имеет уникальные строки и, следовательно, возвращает все записи. Очевидно, проблема DISTINCT.

Одним из решений является сохранение вашего предиката таким же образом и использование предложения GROUP BY для разбивки наборов столбцов и использования функции агрегации MAX() для возврата наибольшего значения.

;WITH C AS 
(SELECT ID 
     , MAX(DateMod) AS DateModified 
     , CONVERT(VARCHAR(10), GETDATE(), 110) AS [Current_Time] 
FROM #Images 
WHERE Type = 'B' 
GROUP BY ID, Type) 

SELECT C.ID, B.Image, C.DateModified, C.[Current_Time] 
FROM C 
LEFT OUTER JOIN (SELECT ID, DateMod, Image FROM #Images) B ON C.ID = B.ID 
                 AND C.DateModified = B.DateMod 

- результаты

ID Image   DateModified Current_Time 
1 0x3078373931 11-12-2015 07-16-2016 
5 0x3078333234 06-26-2015 07-16-2016 
+0

Вы можете использовать 'INNER JOIN', также зависит от того, хотите ли вы, чтобы любые потенциальные пустые строки (и, следовательно,« NULL') возвращались или нет. –

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