2011-12-06 20 views
1

これは前に出てきたことをお詫びしますが、確かな答えは見つかりませんでした。同じテーブルを結合したMysqlユニオン

私はテーブルの3つの列のセットからIDの単一の列を別のテーブルと結合しようとしています。

select文だけで単一の列は次のようになります取得するには:

SELECT id FROM TableA JOIN TableB USING (key1, key2) WHERE someValue = X; 

今、私はそれを理解するように私はそうのようにこれらを取得するために労働組合を行うことができます。

SELECT spec_id1 AS id FROM TableA JOIN TableB USING (key1, key2) WHERE someValue1 = X 
UNION 
SELECT spec_id2 AS id FROM TableA JOIN TableB USING (key1, key2) WHERE someValue2 = Y 
UNION 
SELECT spec_id3 AS id FROM TableA JOIN TableB USING (key1, key2) WHERE someValue3 = Z 

があります(Key1、key2)を使用して、各選択に対して結合されないように、TableA JOIN TableB USINGを再利用する方法はありますか?私はまた、上に表示されていないすべての選択肢に適用されるWHERE条件を持っています。

FROM TableA JOIN TableB USING (key1, key2) WHERE someOtherValue = W 

私はmysqliを使用してこれをPHPで実行しようとしています。私の本来の本能は一時テーブルとクエリを使用することでしたが、mysqliでそれをどのように処理するのかはわかりません。私は後で使用することができる結合されたテーブルに余分なデータがあるので、二重に理想的な複数の次のクエリのためにテーブルを使用することができます。

申し訳ありませんが、これは素朴ですが、私は大きなウェブ開発者ではありません。前もって感謝します。

編集: 私は一時的なテーブルを探していますが、それはその周りの良い方法かもしれないようです。私はそれが何かをする前に、それが良いアイデアかどうかについて何らかの確認をしたいと思っています。

+0

せずにそれを行うことができるようになります。http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html #operator_case私はあなたの状況にどれくらい役に立つのかよく分かりませんが。私はあなたが何をしようとしているのか見ていますが、一度それらの列を組み合わせると、どのような価値がどの列から来たのかをどのように伝えますか? – sgcharlie

+0

私はそれがどの列から来たか気にしません。私がしていることのより具体的な例を示すために、3つの列は、マネージャID、コーディネータID、およびスーパバイザIDに似ています。それはそれのように見えないかもしれませんが、それぞれははっきりと異なる役割です。 私は一般的な管理タイプの電子メールと同じような電子メールを送信しています。彼らの正確な位置にかかわらず、彼らは同じ電子メールを取得するので、他の理由で必要な3つの異なる列を持っているにもかかわらず、彼らはすべて同じ電子メールを取得します。 –

+0

ああ、つまらない。ええ、私はあなたが本当にあなたの心が1つのクエリを実行するように設定されている場合、 'WHERE'句を組み合わせた' CASE'ステートメントを提案します。 – sgcharlie

答えて

1

ショートカットはありません。テーブルのデザインを変更する必要はありません。あなたのアプローチは確固としており、クエリに3つの結合があることを心配する必要はありません。

spec_idsの3つのリストに重複する値がないことがわかっている場合は、UNIONUNION ALLに変更してパフォーマンスを向上させることができます。 spec_idsはすべて別のBaseTableに含まれている場合 - - あなたができる

SELECT spec_id1 AS id 
    FROM TableA 
    WHERE EXISTS 
      (SELECT * 
      FROM TableB 
      WHERE (TableB.key1, TableB.key2) = (TableA.key1, TableA.key2) 
       AND someValue1 = X 
     ) 
UNION    --- or UNION ALL 
    ... 
UNION 
    ... 

か:


書き換え可能な一つは、全体的なUNION計画を変更せずに、EXISTSサブクエリに参加し変更することですこれにより、より良い実行計画が得られるでしょう:

SELECT id 
FROM BaseTable 
WHERE EXISTS 
     (SELECT * AS id 
     FROM TableA 
      JOIN TableB 
      USING (key1, key2) 
     WHERE someValue1 
      AND TableA.spec_id1 = BaseTable.id 
    ) 
    OR EXISTS 
     ( 
     ... 
     ) 
    OR ... 
+0

3つのリストのそれぞれに重複する値があり、3つのリストの間に値がない場合は、UNION ALLでSELECT DISTINCTを実行するか、UNIONでSELECTを実行する方が安いでしょうか? –

+0

私は最初だと思うが、あなたのデータを使ってテストするのがベストだろう。 'UNION ALL'を使うことができるならば、3つのサブクエリを別々に最適化しようとするべきです。 –

+0

それは本当です: - p何らかの理由で私は常に試してみて最適化しようとします。私は、ほとんどのものが即座にテストできるウェブ開発に慣れていない。 ;) –

1

CASE文を試してください。あなたは `CASE`文を試みることができるUNION

SELECT 
    CASE 
     WHEN someValue1 = X THEN spec_id1 
     WHEN someValue2 = Y THEN spec_id2 
     WHEN someValue3 = Z THEN spec_id3 
    END 
AS id FROM TableA JOIN TableB USING (key1, key2) 
WHERE 
someValue1 = X OR someValue2 = Y OR WHERE someValue3 = Z 
関連する問題