4

クエリの例:

select * 
from A join B on A.ID = B.SOMEVALUE
where A.VALUE="something" and
B.ID = 
       (select ID from B where SOMEVALUE = A.ID and 
              THISDATE = (select max(SOMEDATE) from B where ...))

したがって、SQL を読むことができる場合は、いくつかの相関サブクエリを実行して、結合の結果を絞り込んでいることがわかるはずです。(そして、はい、これはひどく単純化されています)。

特定のケースでは、サブクエリ:

select ID from B where SOMEVALUE = A.ID and 
    THISDATE = (select max(SOMEDATE) from B where ...)

複数の値を返すことができるため、エラーが発生します

「サブクエリが複数の値を返しました。サブクエリが =、!=、<、<=、>、>= の後にある場合、またはサブクエリが式として使用されている場合、これは許可されません。」

私は完全に期待しています。これは明らかに良いことではなく、最初からこれらの重複がデータベースに入るのを (うまくいけば) 防止するコードを用意しています (つまり、テーブル Bには

SOMEVALUE = A.ID and max(SOMEDATE)

ただし、エンドユーザーは、ソフトウェアを壊すために私が考えられない方法を見つける点で創造的であるとは言えません。

だから今私の質問に:

最初のサブクエリを次のように変更した方がよいでしょうか

select top 1 * from B ...

この状況が発生した場合/場合に (できれば決して) エラーが表示されないようにするか、エラーが発生するのを防ぎます。私は、トップステートメントを追加せずに、ユーザーに潜在的に間違ったデータを表示させるのではなく、エラーを通過させることに傾いています。このような状況でベスト プラクティスについて考えている人がいるかどうか疑問に思っています...

4

6 に答える 6

11

通常は TOP 1 で十分です。

何百万もの行があり、一致する列にインデックスがない大きなテーブルを考えてみましょう。ただし、探しているのは 1 つの行だけです。

SELECT TOP 1 は、1 つの項目が見つかるとすぐにテーブル スキャンが停止することを意味します。

TOP 1 がなければ、テーブル スキャンは最後まで続きます。

検索を行うためにスキャン (または力ずく) を伴うものと同様です。TOP 1 を使用すると、TOP 1 を使用しない場合よりも平均で 50% 速くなります。

ただし、戻す必要があるものによっては、通常、EXISTS を使用することで実際のパフォーマンスを向上させることができます。

書く代わりに

SELECT * FROM table t
WHERE t.id = (SELECT TOP 1 foreignid from table2)

使用できます

SELECT * FROM table t
WHERE EXISTS (SELECT 1 from table2 WHERE foreignid = t.id)
于 2009-01-30T16:20:51.523 に答える
0

LIMIT 1サブセレクトの最後に使用してみませんか?

于 2009-01-30T16:20:45.127 に答える
0

1 つの行だけを返す場合は、次の 2 つのいずれかを行うことができます。1つ目は、等価チェックを変更して、代わりに封じ込めをチェックすることです

select ID from B where SOMEVALUE = A.ID and 
THISDATE IN (select max(SOMEDATE) from B where ...)

(INに注意)

第二に、あなたができること

select TOP 1 ID from B where SOMEVALUE = A.ID and 
THISDATE IN (select max(SOMEDATE) from B where ...)

1 つの値のみを探している場合。

または、あなたが言ったように、サブクエリを SELECT TOP 1 に変更することもできます。私の意見では、WHERE 句が外部クエリに依存していない限り、ネストされたクエリを 1 回だけ実行し、そこから静的に保存された値に依存する

select ID from B where SOMEVALUE = A.ID and 
THISDATE = (select TOP 1 * from B where ...)

いくつかのオプションがありますが、それらの効率については完全にはわかりません。

于 2009-01-30T16:21:52.253 に答える