web-dev-qa-db-ja.com

Sql:レコードが存在するかどうかを正しくチェックする方法

いくつかのSQL Tuningのドキュメントを読む私はこれを見つけました:

Select count(*)
- 行数をカウントします
- レコードの存在を確認するために不適切に使用されていることが多い

Select count(*)は本当にそれほど悪いのでしょうか。

レコードの存在を確認するための適切な方法は何ですか?

172
systempuntoout

以下のいずれかを使用することをお勧めします。

-- Method 1.
SELECT 1
FROM table_name
WHERE key = value;

-- Method 2.
SELECT COUNT(1)
FROM table_name
WHERE key = value;

最初の選択肢はあなたに結果がないか1つの結果を与えるべきです、2番目のカウントは0か1であるべきです。

あなたが使っているドキュメントは何歳ですか?良いアドバイスを読んだことがありますが、最近のRDBMSの最適化SELECT COUNT(*)のほとんどのクエリオプティマイザーは、理論上の違いがありますが(そして古いデータベースでも)、実際には違いがあることに気付かないでください。

211

私はCount関数をまったく使わないほうがいいです。

IF [NOT] EXISTS ( SELECT 1 FROM MyTable WHERE ... )
     <do smth>

たとえば、データベースに挿入する前にユーザーが存在するかどうかを確認したい場合、クエリは次のようになります。

IF NOT EXISTS ( SELECT 1 FROM Users WHERE FirstName = 'John' AND LastName = 'Smith' )
BEGIN
    INSERT INTO Users (FirstName, LastName) VALUES ('John', 'Smith')
END
173

あなたが使用することができます:

SELECT 1 FROM MyTable WHERE <MyCondition>

条件に一致するレコードがない場合、結果のレコードセットは空です。

18

他の答えはかなり良いですが、不要な行のチェックを防ぐためにLIMIT 1(または 相当する )を追加することも役に立ちます。

12
JesseW

あなたが使用することができます:

SELECT COUNT(1) FROM MyTable WHERE ... 

または

WHERE [NOT] EXISTS 
( SELECT 1 FROM MyTable WHERE ... )

これはSELECT *よりも効率的です。すべてのフィールドではなく、単に各行に値1を選択するだけだからです。

COUNT(*)とCOUNT(列名)の間にも微妙な違いがあります。

  • COUNT(*)はnullを含む全ての行を数えます
  • COUNT(column name)はカラム名のnull以外の出現のみをカウントします
9
Winston Smith
SELECT COUNT(1) FROM MyTable WHERE ...

すべてのレコードをループします。これがレコードの存在のために使うのが悪い理由です。

私は使うだろう

SELECT TOP 1 * FROM MyTable WHERE ...

1レコードを見つけたら、ループを終了します。

8
oski

あなたが使用することができます:

SELECT 1 FROM MyTable WHERE... LIMIT 1

不要なフィールドのチェックを防ぐためにselect 1を使用してください。

不要な行のチェックを防ぐためにLIMIT 1を使用してください。

7
user3059943

その他のオプション:

SELECT CASE
    WHEN EXISTS (
        SELECT 1
        FROM [MyTable] AS [MyRecord])
    THEN CAST(1 AS BIT) ELSE CAST(0 AS BIT)
END
0
Pranav

私はこのように使っています:

IIF(EXISTS (SELECT TOP 1 1 
                FROM Users 
                WHERE FirstName = 'John'), 1, 0) AS DoesJohnExist
0
DiPix