web-dev-qa-db-ja.com

SQLでの整数のLIKE

置き換えることができます=ステートメントを整数のLIKEに置き換えます

たとえば以下は同じものです:

select * from FOOS where FOOID like 2    
// and 
select * from FOOS where FOOID = 2

FOOIDのフィルターがない場合は=を使用できるため、%ではなくLIKEを使用したいと思います...

SQL Server 2005。

編集1 @Martin
enter image description here

23
serhio
select * from FOOS where FOOID like 2

両方がvarcharとして暗黙的にキャストされ、クエリを満たすためにインデックスを使用できないことを意味するため、回避する必要があります。

CREATE  TABLE #FOOS
(
FOOID INT PRIMARY KEY,
Filler CHAR(1000)
)
INSERT INTO #FOOS(FOOID)
SELECT DISTINCT number 
FROM master..spt_values


SELECT * FROM #FOOS WHERE FOOID LIKE 2

SELECT * FROM #FOOS WHERE FOOID = 2

DROP TABLE #FOOS

計画(推定コストに注意してください)

enter image description here

コストの違いを確認するもう1つの方法は、SET STATISTICS IO ONを追加することです

最初のバージョンが次のようなものを返すことがわかります

Table '#FOOS__000000000015'. Scan count 1, logical reads 310

2番目のバージョンが返されます

Table '#FOOS__000000000015'. Scan count 0, logical reads 2

これは、このインデックスでのシークに必要な読み取りはインデックスの深さに比例するため、スキャンに必要な読み取りはインデックス内のページ数に比例するためです。テーブルが大きくなるほど、これらの2つの数値間の不一致が大きくなります。次のコマンドを実行すると、これらの図の両方を確認できます。

SELECT index_depth, page_count
FROM
sys.dm_db_index_physical_stats (2,object_id('tempdb..#FOOS'), DEFAULT,DEFAULT, DEFAULT)
WHERE object_id = object_id('tempdb..#FOOS') /*In case it hasn't been created yet*/
19
Martin Smith

CASEステートメントを使用して、入力文字列を整数に変換します。ワイルドカードを変換する%からNULLへ。これにより、int列全体を暗黙的に文字列に変換するよりもパフォーマンスが向上します。

CREATE PROCEDURE GetFoos(@fooIdOrWildcard varchar(100))
AS
BEGIN
    DECLARE @fooId int

    SET @fooId =
        CASE
            -- Case 1 - Wildcard 
            WHEN @fooIdOrWildcard = '%'
                THEN NULL
            -- Case 2 - Integer
            WHEN LEN(@fooIdOrWildcard) BETWEEN 1 AND 9
            AND @fooIdOrWildcard NOT LIKE '%[^0-9]%'
                THEN CAST(@fooIdOrWildcard AS int)
            -- Case 3 - Invalid input
            ELSE 0
        END

    SELECT FooId, Name
    FROM dbo.Foos
    WHERE FooId BETWEEN COALESCE(@fooId, 1) AND COALESCE(@fooId, 2147483647)
END
5
Anthony Faull

はい、そのまま使用できます。

SELECT  *
FROM    FOOS
WHERE   FOOID like 2   

または

SELECT  *
FROM    FOOS
WHERE   FOOID like '%'  

整数は暗黙的に文字列に変換されます。

これらの条件のどちらも検索条件を変更できないことに注意してください。 e。 fooidでインデックスを使用できます。これにより、常に全表スキャン(またはfooidでの全索引スキャン)が行われます。

3
Quassnoi

これは遅いコメントですが、おそらく他の人が同じことを探しているので、この解決策を見つけることができたので、ここで共有する必要があると思いました:)

問題の簡単な説明:私が抱えていた問題は、ワイルドカードの整数データ型を使用できるようになることでした。私はSQL Serverを使用しているため、構文はSQL Server用です。部門番号を示す列があり、ドロップダウンメニューからページの変数を渡したいと思っています。 'All'オプションもあり、その場合はパラメーターとして '%'を渡します。私はこれを使っていました:

_select * from table1 where deptNo Like @DepartmentID
_

SQLサーバーは_%_を暗黙的にintに変換するため(私のdeptNoの型はintであるため)、数値を渡したときに_@DepartmentID_に対しては機能しませんでした

だから私はdeptNoをキャストし、それが問題を修正しました:

_select * from table1 where CAST(deptNo AS varchar(2)) Like @DepartmentID
_

これは、4などの数値を渡した場合と_%_を渡した場合の両方で機能します。

2
Amir Tofighi

ワイルドカード条件に%の代わりにNULLをパラメーター値として使用します

select * from table1 where (@DepartmentID IS NULL OR deptNo = @DepartmentID)
1
BethS