sql >> データベース >  >> RDS >> Mysql

MySQL-2つのselectステートメントをLIMITを使用して1つの結果に効率的に結合します

    複数のクエリを UNIONと組み合わせることができます 、ただし、クエリの列数が同じである場合に限ります。理想的には、列はデータ型だけでなく意味的にも同じです。ただし、MySQLはセマンティクスを気にせず、より一般的なものにキャストすることでさまざまなデータ型を処理します。したがって、必要に応じてできます。 各テーブルとは異なる意味を持つように列をオーバーロードしてから、上位レベルのコードで適切な意味を決定します(ただし、この方法で行うことはお勧めしません)。

    列の数が異なる場合、または2つのクエリからのデータのより良い/より少ないオーバーロードの配置を実現したい場合は、ダミーのリテラル列をSELECTに挿入できます。 ステートメント。例:

    SELECT t.cola, t.colb, NULL, t.colc, NULL FROM t;
    

    NULLになるように、最初のテーブル用にいくつかの列を予約し、2番目のテーブル用に他の列を予約することもできます。 他の場所(ただし、列名は最初のクエリから取得されるため、すべての名前がそこにあることを確認することをお勧めします):

      SELECT a, b, c, d, NULL AS e, NULL AS f, NULL AS g FROM t1
    UNION ALL -- specify ALL because default is DISTINCT, which is wasted here
      SELECT NULL, NULL, NULL, NULL, a, b, c FROM t2;
    

    この方法で2つのクエリを調整してから、それらをUNIONと組み合わせることができます。 オペレーター; LIMITを適用する UNIONへ 、あなたはあなたの目標を達成することに近づいています:

      (SELECT ...)
    UNION
      (SELECT ...)
    LIMIT 10;
    

    残っている唯一の問題は、上記のように、最初のテーブルの10個以上のレコードが、2番目のテーブルのレコードを「プッシュ」することです。ただし、ORDER BYを利用することはできます これを解決するための外部クエリで。

    すべてをまとめる:

    (
      SELECT
        dr.request_time AS event_time, m.member_name,      -- shared columns
        dr.request_id, dr.member1, dr.member2,             -- request-only columns
        NULL AS alert_id, NULL AS alerter_id,              -- alert-only columns
          NULL AS alertee_id, NULL AS type
      FROM dating_requests dr JOIN members m ON dr.member1=m.member_id 
      WHERE dr.member2=:loggedin_id
      ORDER BY event_time LIMIT 10 -- save ourselves performing excessive UNION
    ) UNION ALL (
      SELECT
        da.alert_time AS event_time, m.member_name,        -- shared columns
        NULL, NULL, NULL,                                  -- request-only columns
        da.alert_id, da.alerter_id, da.alertee_id, da.type -- alert-only columns
      FROM
        dating_alerts da
        JOIN dating_alerts_status das USING (alert_id, alertee_id)
        JOIN members m ON da.alerter_id=m.member_id
      WHERE
        da.alertee_id=:loggedin_id
        AND da.type='platonic'
        AND das.viewed='0'
        AND das.viewed_time<da.alert_time
      ORDER BY event_time LIMIT 10 -- save ourselves performing excessive UNION
    )
    ORDER BY event_time
    LIMIT 10;
    

    もちろん、結果セットの各レコードを読み取るときに、処理している行のタイプを決定するのはあなた次第です(request_idをテストすることをお勧めします)。 および/またはalert_id NULLの場合 値;または、各レコードがどのテーブルから発生したかを明示的に示す列を結果に追加することもできますが、それらのidがあれば同等である必要があります。 列はNOT NULL




    1. SQL Server でグローバル関数を作成できますか?

    2. シーケンスオブジェクトからデータベースで生成されたIDを使用したOracleViewの作成

    3. PostgreSQLでアイドル状態の接続を自動的に閉じる方法は?

    4. MySqlのアップサートと自動インクリメントはギャップを引き起こします