ホームページ > データベース > mysql チュートリアル > FIND_IN_SET() と IN(): 1 つはすべての結果を返し、もう 1 つは最初の結果のみを返すのはなぜですか?

FIND_IN_SET() と IN(): 1 つはすべての結果を返し、もう 1 つは最初の結果のみを返すのはなぜですか?

Linda Hamilton
リリース: 2024-12-11 20:46:13
オリジナル
934 人が閲覧しました

FIND_IN_SET() vs. IN(): Why Does One Return All Results While the Other Only Returns the First?

FIND_IN_SET() と IN(): クエリ結果の矛盾を理解する

リレーショナル データベースをクエリするときは、その違いを理解する必要がありますFIND_IN_SET() 関数と IN() 関数の間。この記事では、特定のデータベース シナリオにおけるそれらの動作を検証します。

問題:

orders と company という 2 つのテーブルについて考えます。 order テーブルには、会社 ID のカンマ区切りリストを保持する AttachedCompanyIDs 列が含まれています。会社テーブルには実際の会社名が含まれています。 FIND_IN_SET() 関数を使用して注文に関連付けられた会社名を取得するクエリを実行すると、期待されるすべての結果が返されます。ただし、クエリ内で FIND_IN_SET() を IN() に置き換えると、最初の会社名のみが返されます。

原因:

IN() 関数は、attachedCompanyID を単一のものとして解釈します。整数ですが、FIND_IN_SET() はそれを文字列として扱います。 AttachedCompanyIDs が整数としてキャストされる場合、最初の数字以外の文字 (カンマ) までの数字のみが保持されます。したがって、IN() クエリは、カンマ区切りリストの最初の番号に関連付けられた会社のみを返します。

解決策:

この問題を回避するために、PostgreSQL は次のことを提供します。より堅牢なソリューション:

SELECT name
FROM orders
JOIN company
ON companyID = ANY(('{' || attachedCompanyIDs || '}')::INT[])
WHERE orderID = 1;
ログイン後にコピー

このクエリは、ANY() 関数を利用してキャストします。 AttachedCompanyIDs を配列として使用し、companyID のインデックスを効果的に使用できるようにします。

Update:

配列のサポートがない MySQL データベースの場合は、別のアプローチを使用できます。 :

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);
ログイン後にコピー

このクエリは、潜在的な位置を反復して、attachedCompanyID から一致する部分文字列を抽出します。会社ID。これには複数の結合が含まれますが、カンマ区切りリスト内の会社 ID の数が限られているシナリオでも引き続き機能します。

以上がFIND_IN_SET() と IN(): 1 つはすべての結果を返し、もう 1 つは最初の結果のみを返すのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート