1

ID と場所に基づいて次の最新のエントリの情報を取得し、それを実行中のクエリに追加しようとしています。テーブル内の 2 番目に新しいエントリではなく、ID に基づく前のエントリのみです。

これが可能かどうかはわかりませんが、それを行う方法や、どの方向に進むべきかさえわかりません。

以前のプログラマーが行った方法は次のとおりです。

SELECT -- blah blah blah
       , (SELECT TOP 1 CAST(id AS VARCHAR) + '~' + CONVERT(VARCHAR,  creation_date,   120)
          FROM header hdr2 
          WHERE hdr2.id < hdr.id 
                AND hdr2.location = hdr.location 
          ORDER BY hdr2.id DESC) AS "prev_info"
FROM header hdr 
/*blah blah blah*/

彼が単一のサブクエリのみを使用し、すべてをその 1 つの列に入れようとした理由を理解していますが、これを最適化しようとしており、他のより簡単で効率的な方法でそれを行いたいと考えています。

答えが目の前にあるような気がしますが、手を伸ばして把握することはできません。これ以上説明する必要がある場合は、遠慮なくお尋ねください。

4

3 に答える 3

2

ROW_NUMBERを使用する場合は、これでうまくいくと思います。

With rownumbers as 
(
  SELECT
    ROW_NUMBER() OVER (partition by location ORDER BY id ASC) AS rownumber,
    id, location
  FROM header 
)
SELECT id, location from rownumbers
WHERE rownumber = 2

読みやすいですか?読者次第だと思います。それはより効率的ですか?実行計画を確認する必要があります。

于 2012-06-05T17:44:54.473 に答える
1

使用を検討してくださいouter apply

select  -- blah blah blah
,       prev_info.*
from    header hdr 
outer apply
        (
        select  top 1 id
        ,       creation_date
        from    header hdr2 
        where   hdr2.id < hdr.id 
                and hdr2.location = hdr.location 
        order by
                hdr2.id desc
        ) as prev_info
于 2012-06-05T17:39:09.787 に答える
1

私があなたを正しく理解している場合は、クロスアプライを使用してすべての列を一度に取得できます。

SELECT -- blah blah blah
FROM header hdr 
  cross apply(
          SELECT TOP 1
            hdr2.*
          FROM header hdr2 
          WHERE hdr2.id < hdr.id 
                AND hdr2.location = hdr.location 
          ORDER BY hdr2.id DESC
) AS prev_info
/*blah blah blah*/

選択したサブクエリと同じことを行いますが、複数の列を返すことができるため、連結された1つの列からすべてを解析する必要がありません。

于 2012-06-05T17:39:16.537 に答える