2016-07-15 6 views
1

私は今抽出する必要があるデータベースに画像を持っています。イメージ列のタイプはvarbinary(max)です。T-SQLはMax(Date)から画像を抽出します

JOINまたはサブクエリーを使用していくつかの例を試してみましたが、開発されたクエリは、画像用ではない場合には機能します。 DISTINCTMAX(date)を使用しても、古い画像は消去されません。多くのIDには複数の画像があります。 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を強制し、それはまだ古い画像がなくなるわけではありません。各IDに最新のタイプ 'B'イメージが必要です。私はあなたがこのような何かをしたいかなり確信して image, ID, DateModified, TodaysDate (GetDate)

+0

。それは一定の時間かトップnレコードですか? – H20rider

+0

@ H20rider "各IDの最新のタイプ 'B'イメージ"(IDによる)グループごとの日付順の「TOP 1」、タイプ= Bの場合 –

+0

@Daveは私の答えを参照してください。 'DISTINCT'節が適切に使用されたときにそれをエミュレートすることはできますが、あなたは' GROUP BY'を使用していません。 –

答えて

4

である私は、出力のために必要なもの

2012のSQL Serverに取り組んでいます。

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アナライザへのクエリでは、初めてクエリを実行したときに覚えていても、結果に表示される時間がもう少し長くかかったことを覚えています。私はこの現象についていくつかの研究を行い、非常によく書かれた[記事](http://guyharrison.squarespace.com/blog/2009/6/4/partition-by-versus-group-by.html)の分析について知った関数とGROUP BY。 IOは低下していますが、前者はCPUとメモリのコストを上昇させます(1つのテーブル読取りスキャンのみ)。記事は魅力的で、私の最初の認識に挑戦しています。 :) –

+0

@clifton_h - さらに興味深いのは、この本はオラクルに関するものなので、SQL Serverを使用しているため、パフォーマンス分析は関係がありません。 –

+0

Sean、解決に感謝します。私が探しているレコードを取得します。私はまた、以下の解決策を試して、さらに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

このクエリは、私が先週の試行から期待していたレコードの数を生成します。上記のSeanのソリューションも良い解決策です。しかし、それは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が問題です。

1つの解決策は、述語を同じに保ち、列のセットを破棄し、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 

- TGTレコードのためのあなたの基準は何か結果

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')を返すかどうかによって決まります。 –

関連する問題