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

PostgreSQLでUNIONの後に順序が保持されますか?

    基本的に、クエリはそもそも正しくありません。 UNION ALLを使用する UNIONではありません または、重複するエントリを誤って削除してしまいます。 (同じメール間で証跡を切り替えることができないと言うことは何もありません。)

    UNION ALLのPostgres実装 しない限り、追加された順序で値を返します。 ORDER BYを追加します 最後に、または結果を使用して他のことを行います。
    ただし、各SELECT ORDER BYでない限り、任意の順序で行を返します が追加されます。テーブルには自然な順序はありません。

    同じことはない UNIONの場合はtrue 、重複の可能性を排除するためにすべての行を処理する必要があります。重複を判断するにはさまざまな方法があります。結果として得られる行の順序は、選択したアルゴリズムによって異なり、実装に依存し、完全に信頼性がありません。ただし、ORDER BY 追加されます。

    したがって、代わりに使用してください:

    SELECT * FROM iter1
    UNION ALL  -- union all!
    SELECT * FROM iter2;
    

    信頼できる並べ替え順序を取得し、「成長の記録をシミュレート」するには、次のようなレベルを追跡できます。

    WITH RECURSIVE all_emails AS (
       SELECT  *, 1 AS lvl
       FROM    audit_trail
       WHERE   old_email = '[email protected]'
    
       UNION ALL  -- union all!
       SELECT t.*, a.lvl + 1
       FROM   all_emails  a
       JOIN   audit_trail t ON t.old_email = a.new_email
    )
    TABLE  all_emails
    ORDER  BY lvl;

    db <> fiddle こちら
    古い sqlfiddle

    余談:old_emailの場合 定義されていませんUNIQUE 何らかの方法で、複数のトレイルを取得できます。明確に保つには、一意の列(または列の組み合わせ)が必要になります。他のすべてが失敗した場合は、内部タプルID ctidを(ab-)使用できます トレイルを区別するために。ただし、独自の列を使用する必要があります。 (フィドルに例を追加しました。)

    検討してください:



    1. 異種データベースレプリケーションの構成–SQLServerからOracleへ

    2. 関数またはストアドプロシージャからテーブルを返すtsql

    3. フォームに複数のフィールドを送信する(PHP)

    4. 最後の(最新の)明確な最高値を取得する