1

ランキング アルゴリズムを使用して検索ルーチンを作成しており、これを 1 回のパスで取得したいと考えています。

私の理想的なクエリは次のようなものになります....

select *, (select top 1 wordposition
           from wordpositions
           where recordid=items.pk_itemid and wordid=79588 and nextwordid=64502
          ) as WordPos,
      case when WordPos<11 then 1 else case WordPos<50 then 2 else case WordPos<100 then 3 else 4 end end end end as rank
from items 

そのケースで WordPos を使用することは可能ですか? 無効な列名 'WordPos' というエラーが発生します。

ケースごとにサブクエリをやり直すことができることは知っていますが、実際にはケースを再実行すると思いますよね?

例えば:

select *, case when (select top 1 wordposition from wordpositions where recordid=items.pk_itemid and wordid=79588 and nextwordid=64502)<11 then 1 else case (select top 1 wordposition from wordpositions where recordid=items.pk_itemid and wordid=79588 and nextwordid=64502)<50 then 2 else case (select top 1 wordposition from wordpositions where recordid=items.pk_itemid and wordid=79588 and nextwordid=64502)<100 then 3 else 4 end end end end as rank from items 

それは機能します....しかし、本当に毎回同じクエリを再実行していますか?

最初に実行するときは遅いが、その後の実行は速いため、テストから判断するのは難しい....キャッシングです...つまり、最初の行で初めて実行したとき、その後の3回キャッシュから結果を取得しますか?

これを行うための最良の方法が何であるかに興味があります...ありがとう!ライアン

4

2 に答える 2

1

サブクエリを使用してこれを行うことができます。質問にmysqlのタグが付けられていても、SQL Serverの構文に固執します。

select i.*,
       (case when WordPos < 11 then 1
             when WordPos < 50 then 2
             when WordPos < 100 then 3
        else 4
        end) as rank
from (select i.*,
             (select top 1 wpwordposition
              from wordpositions wp
              where recordid=i.pk_itemid and wordid=79588 and nextwordid=64502
             ) as WordPos
      from items i
     ) i;

caseこれにより、ステートメントも簡素化されます。複数の条件を処理するためにネストされた case ステートメントは必要ありません。複数のwhere句だけです。

于 2013-11-01T22:40:55.073 に答える
0

いいえ。出力句で導入された識別子 (サブクエリに由来するという事実は関係ありません)は、同じ SELECT ステートメント内では使用できません。

ここにいくつかの解決策があります:

  1. JOIN 1を使用してクエリを書き直します。これにより、問題が完全に解消され、RA にうまく適合します。
  2. 大文字と小文字を使用して別の SELECT 内のサブクエリで SELECT 全体をラップします。外側の選択は、内側の SELECT の出力句によって導入された識別子にアクセスできます。
  3. CTE を使用します (SQL Server の場合)。これは、識別子を導入できるという点で #2 に似ています。

ケースごとにサブクエリを「書き直す」ことは非常に厄介ですが、それでも同等の計画になるはずですが、クエリプロファイルを表示してください! - クエリの結果は不揮発性であるため。そのため、そもそも「再実行」を避けるために、サブクエリ/サブクエリをJOINに移動する必要があるクエリプランナーによって、同等のサブクエリを安全に移動できます。


1これは私の好みの方法である JOIN を使用するための変換です。(クエリを JOIN に関して「簡単に」記述できない場合は、間違ったことを要求しているか、スキーマ設計の問題を示している可能性があります。)

select
   wp.wordposition as WordPos,
   case wp.wordposition .. as Rank
from items i
left join wordpositions wp
  on wp.recordid = i.pk_itemid
where wp.wordid = 79588
  and wp.nextwordid = 64502

ここで、検証すべき多重度(つまり、一意である)について仮定しました。wordidこの多重度が有効ではなく、それ以外の方法で修正できない場合 (実際に SQL Server を使用している場合)、ROW_NUMBER()CTE を使用することをお勧めします。

于 2013-11-01T22:34:42.660 に答える