bugfix> sql > 投稿

カンマの前後の値を選択するためのSQLクエリ

employeeというテーブルがあり、3つのフィールドがあります。Id、Name、Departmentid DepartmentIdでは、3つのID 201,301,401で構成されます。

これから実行したい

Select * from employee where DepartmentId =301

回答 5 件
  • これは、常に真ん中の数字で一致させたい場合に機能します。 301  あなたの例では。

    SELECT *
    FROM employee
    WHERE 
        SUBSTRING ( 
            DepartmentId, 
            CHARINDEX(',', DepartmentId, 0) + 1, 
            CHARINDEX(',', DepartmentId, CHARINDEX(',', DepartmentId, 0) + 1) - CHARINDEX(',', DepartmentId, 0) - 1
        ) = '301'
    
    

    301 の場合  そのフィールドの任意の場所にあることができ、あなただけの LIKE を使用することができます

    SELECT *
    FROM employee
    WHERE DepartmentId LIKE '%301%'
    
    

  • SELECT * FROM EMPLOYEE WHERE DEPARTMENTID LIKE '%301%'
    
    

    それが機能する場合でも、DBがどのように設計されているのか、なぜコンマが必要なのかはよくわかりません

  • parsename() を使用できます  関数:

    . . . 
    where parsename(replace(DepartmentId, ',', '.'), 2) = 301;
    
    

    しかし、 like  述語も便利です:

    . . . 
    where DepartmentId LIKE '%301%';
    
    

  • カンマ区切りの列はアンチパターンです。部門を正規化します。

    ただし、次の1つの方法があります。

    select * from employee 
    where '301' in (SELECT value FROM STRING_SPLIT(department, ','))
    
    

  • 1301または3011のような部門がある場合、単純なLIKEは失敗する可能性があります

    次のSQLコードを確認してください

    select * from employees where ','+departmentid+',' like '%,301,%'
    
    

    他のオプションは、departmentid列を各部門ID値リストに分割することです

    SQL Server 2016より前のSQL Serverがある場合は、独自のカスタムSQL文字列分割関数が必要です。 その後、次のSQLクエリを使用できます

    select e.* 
    from employees as e
    cross apply dbo.split(departmentid,',') as s
    where s.val = '301'
    
    

    SQL Server 2016またはSQL Server 2017で作業している場合、string_splitビルトインSQL関数は、CROSS APPLYクエリで次のように再び使用できます。

    SELECT e.* 
    FROM employees as e
        CROSS APPLY STRING_SPLIT(departmentid, ',')
    WHERE value = '301'
    
    

    最後の1つの方法は、次のようにコンマ区切りリストをXMLデータに変更することにより、SQL XMLクエリを使用することです。

    select 
        Id, Name, sqlXML.value('.','varchar(5)') as DepId
    from (
        SELECT 
            Id, Name, 
            convert(xml, '<root><t>' + REPLACE(Departmentid, ',', '</t><t>') + '</t></root>') as dlist
        FROM employees
    ) tbl
    CROSS APPLY dlist.nodes('/root/t') as XMLData(sqlXML)
    WHERE sqlXML.value('.','varchar(5)') = '301'
    
    

あなたの答え