ホームページ >データベース >mysql チュートリアル >FIND_IN_SET() と IN(): カンマ区切り値にそれぞれを使用する必要があるのはどのような場合ですか?
FIND_IN_SET() と IN(): クエリの難題を明らかにする
データベース クエリの領域では、さまざまな関数間のニュアンスを理解することが重要です。重要な。このような違いの 1 つは、FIND_IN_SET() と IN() を比較するとき、特にコンマ区切りの文字列として格納された値をクエリするときに発生します。
クエリの不一致
2 つのテーブルを考えてみましょう。 「orders」と「attachedCompanyIDs」列にはカンマ区切りの企業識別子が含まれており、 「company」列と「companyID」列、および対応する会社名。次のクエリは、FIND_IN_SET() を使用して注文に関連付けられた会社名を効果的に取得します:
SELECT name FROM orders, company WHERE orderID = 1 AND FIND_IN_SET(companyID, attachedCompanyIDs)
ただし、IN() を使用した同様のクエリでは予期しない結果が得られます:
SELECT name FROM orders, company WHERE orderID = 1 AND companyID IN (attachedCompanyIDs)
隠れた落とし穴
根本原因は MySQL の処理方法にありますAttachedCompanyID を整数にキャストする場合のカンマ区切りの値。キャストでは、数字以外の最初の部分が切り捨てられ、実質的に文字列が最初のカンマ区切りの値に減らされます。
たとえば、attachedCompanyID が '1,2,3' に設定されている場合、IN() クエリは誤って実行されます。
companyID IN (1)
これは、IN() クエリが最初の会社名のみを返すのに対し、FIND_IN_SET() がすべての会社名を返す理由を説明しています。 3.
制限の克服
この問題に対処するには、カンマ区切りの文字列を適切に処理する代替アプローチを検討してください。 PostgreSQL では、配列を使用できます。
SELECT name FROM orders JOIN company ON companyID = ANY(('{' || attachedCompanyIDs || '}')::INT[]) WHERE orderID = 1
残念ながら、配列は MySQL ではサポートされていません。値の数が限られている場合 (たとえば、5 未満)、クロス結合と文字列操作を使用して回避策が可能です:
SELECT name FROM orders CROSS JOIN ( SELECT 1 AS pos UNION ALL SELECT 2 AS pos UNION ALL SELECT 3 AS pos UNION ALL SELECT 4 AS pos UNION ALL SELECT 5 AS pos ) q JOIN company ON companyID = CAST(NULLIF(SUBSTRING_INDEX(attachedCompanyIDs, ',', -pos), SUBSTRING_INDEX(attachedCompanyIDs, ',', 1 - pos)) AS UNSIGNED)
以上がFIND_IN_SET() と IN(): カンマ区切り値にそれぞれを使用する必要があるのはどのような場合ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。